I've been trying for a while to understand how GORM works, and I think I've got it down. However, I'm having a heck of a time getting my relationships correct.
Here is my database schema setup (2 tables):
Table - Users
userhash varchar(255)
firstname varchar(255)
lastname varchar(255)
Table - Logs
userhash varchar(255)
accessdate date
There are no foreign key and primary key constraints defined in the tables. However, in the users table the userhash will be unique. I didn't design it this way, but I have to use it like this.
Now for my Grails domain classes:
Class - Users
class Users {
String userhash;
String firstname;
String lastname;
static hasMany = [logs: Logs]
}
Class - Logs
class Logs {
String userhash;
Date accessdate;
static belongsTo = Users;
}
In my controller, I do the following:
def user = Users.findByUserhash("nraboy");
println user.firstname;
println user.logs;
It prints out the correct firstname, but when I try to display the logs, it is null or empty. Am I requesting the data incorrectly for child tables or am I missing something somewhere in the domain class design?
I've tried to do the following, but had now luck as well:
Class - Logs
static mapping = {
id generator: "assigned", name: "userhash", type: "string"
}
Class - Users
static mapping = {
userhash generator: "foreign"
}
I figured the above would let me manually define the primary key and foreign key via code since it didn't exist int he tables. No luck though.
Any help would be appreciated.
Thanks,
It looks like you may have to do something with in Users for the logs association to force the foreign key to be in the Logs table, as it is. See the GORM docs One-to-Many Mapping section. Perhaps something like:
static hasMany = [logs: Logs]
static mapping = {
logs column: 'userhash'
}
I would be curious to hear if this worked...
Related
I am trying to create a rest API. I have already a database. I want to create a struct linked to a database table. But when I run the project beego automatically creates an "id" primary key for the model registered. How to avoid this in beego?
My code example:
Model:
type Person struct {
PersonId string `json:"person_id"`
name string `json:"name"`
email string `json:"email"`
}
Problem: Encounter need a primary key field when using beego
It creates an id field in db table with default null value.
Note: person_id is the primary key in person table.
If you want Beego’s ORM to have a different primary key, you should use this:
type Person struct {
PersonId int64 `orm:"pk" json:"person_id"`
name string `json:"name"`
email string `json:"email"`
}
You can check the official documentation here in the primary key section:
Beego Model Definition
This might be happening because when creating your table you have primary_key set to auto. Which is the default Beego behaviour.
Please check this article also:
https://developpaper.com/question/beegos-orm-gives-the-primary-key-value-every-update-delete-read/
I am a newbie to Grails and am having a lots of problems in a many to many relationship especially when the mappedBy comes into picture. Here is the exact problem that I am facing.
I have two domain classes which have a many to many relationship.
class Address {
Long id
String addName
static hasMany = [policy: Policy]
static belongsTo=[Policy]
Date lastUpdated
Date dateCreated
}
and
class Policy {
int id
int policyId
Date lastUpdated
Date dateCreated
static hasMany = [addressSource:Address,addressDestination: AddressSet]
}
Now this creates 4 tables, namely : address, policy, policy_src_add and policy_dest_add
The problem that I am facing is with the 'show' view (The views are the standard ones generated by Grails by the generate-views command).
In the show view of Address I can see the Policies that are referenced by policy_dest_add but not the ones that are referenced by policy_src_add.
For ex : Let us assume there is a policy:"PK" which has addressSource:"AS"(lets say id=1) and a addressDestination :"AD"(lets say : id=2)
When i go to the show view of "AD" (which is /address/show/2 ) I can see the Policy "PK" but when i go to the show view of "AS" (which is /address/show/1 ) I can NOT see the Policy "PK" in it.
Can someone please help me.Is this a view generation problem in case of many to many relationships in grails? Or is it just something I am missing ?I have tried using mappedBy in the Address as follows but to no avail :
static mappedBy = [policy:"addressSource", policy:"addressDestination"]
Thanks a ton,
Manas Shukla
I have a domain class UserProfile which has one to one relationship with another domain class User.The Structure of the domain is provided.
сlass UserProfile {
String fio
String position
String phone
String email
static belongsTo = [user: User]
static constraints = {
// some constraints
}
static mapping = {
//some mapping; user property is not mapped
}
I need to write a native sql query in Grails for UserProfile domain and I don't know how to refer to user property(static belongsTo = [user: User]). I have tried USER_ID but it is not working.
I can't name the column directly using mapping section; I just need to find out how user column in UserProfile domain is named in database and how it can be called in native sql query.
Very Simple if i got your question ,Grails gorm convention for storing fileds in data base is:
Like
user_profile for UserProfile -Domain
and all fileds are speparedted by underscores and most of the time gorm adds _id after a foreign key reference /or a GORM relationship like above One to One and one to Many
[belongsTo=[user]] .
Inside SQL Table
mysql describe user_profile ;
----------------------------------------------------------------
User_Profile
----------------------------------------------------------------
id
version
foo varchar(50)
postion
email
user_instance_id int
-------------------------------------------------------------------
NATIVE SQL QUERY WILL BE :
'select up.user_instance_id from user_profile as up '
the Get all the userInstance objects by querying the user table
'select * from user where user.id = 'the id you get it from the above query'
I hope you have some idea on this please ,if i didnt get it let me know.
I believe if you define user inside UserProfile, then you can access it and will automatically be mapped? It works in my previous projects, I hope it will work with this.
сlass UserProfile {
String fio
String position
String phone
String email
static belongsTo = [user: User]
User userInstance;
static constraints = {
// some constraints
}
Then you can use it
UserProfile.executeQuery("select up.userInstance from UserProfile up")
I have this code in my model for "Application", I'm trying to get all the related "Campaign" objects
public function relations()
{
return array(
'campaigns' => array(self::HAS_MANY, 'Campaign', 'appKey'),
);
}
My problem is, the 'appKey' field in the campaigns table is not the primary key of the applications table and this is what Yii is using to try and find the campaigns.
The primary key of my applications table is 'id' but I would like it to use 'appKey'. How can I update my relations method to do this without making it the primary key?
Thanks.
You could set up a named scope in the Campaign model, like so:
public function byApplication($appKey)
{
$this->getDbCriteria()->mergeWith(array(
'condition'=>'appKey = :appkey',
'params'=>array('appKey'=>$appKey),
));
return $this;
}
And call it like this:
$campaigns = Campaign::model()->byApplication($appKey);
Or, as Irobb said, just set up a query function in your Application model instead of using an actual Relation, like so:
public function getCampaigns() {
return Campaign::model()->findallbyAttributes(array('appKey'=>$this->appKey));
}
And call it like a regular relation on your Application $model:
$campaigns = $model->campaigns; // remember with Yii you can call getters w/o the 'get'
A couple of things... AR is primarily useful for modeling a single table to a class, with a well-defined primary key... Anything else I would use the query builder.
Note: AR is not meant to solve all database-related tasks. It is best
used for modeling database tables in PHP constructs and performing
queries that do not involve complex SQLs. Yii DAO should be used for
those complex scenarios.
http://www.yiiframework.com/doc/guide/1.1/en/database.ar
AR relies on well defined primary keys of tables. If a table does not
have a primary key, it is required that the corresponding AR class
specify which column(s) should be the primary key by overriding the
primaryKey() method as follows,
public function primaryKey() {
return 'id';
// For composite primary key, return an array like the following
// return array('pk1', 'pk2'); }
I have a Class which looks something like this:
public class User {
public virtual int ID;
public virtual string Name;
public virtual IList<int> userRights;
}
I want to make a UserMap : ClassMap<User>
Mapping the name is no problem however i cant seem to figure out how to map the userRights.
Table looks like
UserTable
User_id int
User_Name nvarchar
User_group int
UserRights
User_group int
RightID int
How would you map this ?
Well if you want a List you need an index. So I would recommend just making it an ICollection unless the ordering is significant.
The mapping should look something like:
HasMany(x=> x.userRights).Element("RightID").AsBag();
However, upon looking at your tables, I noticed something odd. You're trying to use a one-to-many without having the primary key in the User_Rights table. If you had User_Id in UserRights the above should work.
Otherwise it looks like there's a UserGroup, which should be modeled by your classes.