Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Routing to default EDIT template with composite key in crud Play 1.2.4

I have a composite key of User Id and User Role in my DB.

For mapping the DB with the model, below is the code:

    @Id
@Column(name="ID")
public int userId;
@Id
    @Column(name="USER_ROLE")
public String userRole;
......
    ......
    @Override
public String toString() {      
    return userId;
}

Presently I am able to display the list of users and also able to add new user for my application. But When I try to route to the default "Edit" template by clicking a User Id then I receive an error: "No Route".

Also, I can see that on click of an user, the composite id is not getting send as the URL, in fact some object is being appended at the end of the url (which might be a reason for this).

Kindly let me know how to display the default edit screen when we have a composite key in the DB. I have been struggling with this issue since quite some time but did not got any reference materials in documentation :(

like image 819
user182944 Avatar asked Jun 12 '13 06:06

user182944


1 Answers

The Play CRUD controller doesn't work well with composite keys. Here's how you can work around it.

First, decide on a stringified format for your composite keys - in the example below I've just taken the two keys (ssn, accountId) and concatenated them separated with a "-".

In your model override the _key and findById methods from GenericModel and JPABase as follows:

package models;

import play.db.jpa.GenericModel;

import javax.persistence.Entity;
import javax.persistence.Id;    

@Entity
public class Part extends GenericModel {
    @Id
    public int ssn;
    @Id
    public int accountId;
    public String name;

    /**
     * Find a part by its composite id ("ssn-accountId")
     */
    public static Part findById(String id) {
        // Split the composite id to extract ssn and accountId
        String[] elements = id.split("-");
        int ssn = Integer.valueOf(elements[0]);
        int accountId = Integer.valueOf(elements[1]);

        return Part.find("ssn=? AND accountId=?", ssn, accountId).first();
    }

    /**
     * Return a composite id ("ssn-accountId")
     */
    public String _key() {
        return ssn + "-" + accountId;
    }
}

Next override the show method in your controller:

    package controllers;

    import models.Part;

    public class Parts extends CRUD {

    /**
     * CRUD show method doesn't know how to handle composite ids.
     *
     * @param id composite of ssn + "-" + accountId
     * @throws Exception
     */
    public static void show(String id) throws Exception {
        // Do not rename 'type' or 'object'
        ObjectType type = ObjectType.get(getControllerClass());
        notFoundIfNull(type);
        Part object = Part.findById(id);
        notFoundIfNull(object);
        render("CRUD/show.html", type, object);
    }
}

That's it.

like image 159
ct_ Avatar answered Nov 18 '22 15:11

ct_