GORM/Grails - add extra column to a joinTable expression - grails

I have a Domain Class setup similar to this
class NewsStory {
String headline
static hasMany = [channels:Channel]
static mapping = {
table 'NewsStory'
addresses joinTable:[name:'Article_Channel', key:'ArticleId', column:'ChannelId']
}
}
in the Article_Channel table i need to have an extra column populated called ArticleType say. Its value will always be the same e.g. 'news' for this domain class, but will be differnt for others e.g. 'blog'
Channel is just something like 'Security' etc
Is there a way?
Thanks

One option would be be to create your own many-to-many mapping class and add the field in there.
http://grails.org/Many-to-Many+Mapping+without+Hibernate+XML
So, for example:
class ArticleChannel {
NewsStory newsStory
Channel channel
String articleType
}
Then, your NewsStory and Channel classes would hasMany the ArticleChannel class.

Related

hasMany mapping table not created

I am having a GORM issue.
I try to map one domain Object with another with hasMany.
class PrototypePriceModifierCode {
...
static hasMany = [activitys:Activity]
...
}
Since I don't need a back reference in Class Activity I don't have any reference to PrototypePriceModifierCode.
Having only this creates my mapping table as expected (1).
prototype_price_Modifier_code_id activity_id
In the Activity, I need a reference to a PrototypePriceModifier, which has nothing to do with the above mapping table.
The problem is that the mapping table is not generated anymore as soon as I define
class Activity{
...
PrototypePriceModifierCode prototypePriceModifierCodeAttached
How can I get the mapping table created and having a reference to PrototypePriceModifierCode in my Activity domain class?
Try like this:
class Activity {
static belongsTo = [PrototypePriceModifierCode]
}
This way, there will be a column in the activity table for PrototypePriceModifierCode instead of creating a separate table for hasMany.
When Activity does not have the prototypePriceModifierCodeAttached property, the hasMany in PrototypePriceModifierCode results in a uni-directional one-to-many association. In the database, this is implemented with a mapping table.
However, when Activity has the prototypePriceModifierCodeAttached property the association changes to a bi-directional one-to-many. In the database this means the activity table has a foreign key pointing to it's prototype_price_modifierCode, so the mapping table is not used. You can read more about these differences here.
"prototypePriceModifierCodeAttached" property
If you want a uni-directional one-to-many and the property Activity.prototypePriceModifierCodeAttached, you can create a getter method which looks up the PrototypePriceModifierCode:
class Activity {
PrototypePriceModifierCode getPrototypePriceModifierCodeAttached() {
PrototypePriceModifierCode.where {
activitys.id == this.id
}.get()
}
}
The downside here is that the property is inaccessible to GORM; can't query on it.
"price_modifier_code_id" column
On the other hand, if what you want is a price_modifier_code_id column in the activity table, you can add it as a long:
class Activity {
long prototypePriceModifierCodeAttached
static mapping = {
prototypePriceModifierCodeAttached column: 'price_modifier_code_id'
}
}
This makes it possible to use GORM queries on the property, but only on the PrototypePriceModifiedCode ID, not the domain class instance itself.
A combo
You can combine both approaches, as long as you're willing to do a bit of maintenance:
class Activity {
long priceModifierCodeId // <--- You gotta maintain this property manually.
PrototypePriceModifierCode getPrototypePriceModifierCodeAttached() {
PrototypePriceModifierCode.get(priceModifierCodeId)
}
}
Note: activitys is misspelled. It should be activities.
I ended up using String saving comma separated ids.
String activitys
this.activitys.split(',')each{
p.activitys.add(Activity.get(Long.parseLong(it)))
}
As I don't need referencial integrity here this works fine for me.

Creating one-to-many & many-to-many for same domain class in grails

I want to create a domain class as like , One user can post many orders [Bidirectional] and one order can be liked by many users [unidirectional].
I have written a domain class as shown below ,
Class User {
String userName;
List orders
static hasMany = [Order]
}
Class Order {
String orderId
String orderName
//Indicates this order belongs to only one user
static belongsTo =[owner : User ] // Bidirectional
//Indicates order can be liked by many users
static hasMany = [likedUser : User] //Unidirectional
}
But I am getting am error saying invalid schema . Any body please help...
This post looks similar to my question but I am not getting , Please help.
First, order is a reserved word in SQL. Since GORM by default creates a table with the same name as your class, you'll need to either rename your class or provide a different name to use when mapping to SQL tables.
For example:
class Order {
static mapping = {
table 'user_order'
}
// ...
}
Another problem is that Order contains two associations to User. You need to tell GORM which one of these that is the bi-directional association from User to Order. That can be achieved using mappedBy, like this:
class User {
String userName
static hasMany = [orders: Order]
static mappedBy = [orders: 'owner']
}
Hope this helps.

Retrieve collection in domain class from Database

We use dynamic scaffolding in our project and hence place maximum coding in Domain itself.
I have a requirement where I want to retrieve a collection for a Domain class property from the same domain class.
Example :
class Person{
String name
String school
}
school property should be a dropdown containing list of all schools so far available in the Person table. If no value available, it can be empty dropdown.
Any suggestions to achieve this in domain class itself?
That is what
static hasMany is for: http://grails.org/doc/latest/ref/Domain%20Classes/hasMany.html
in your case, something like below will work , once you create a School Domain object:
class Person{
...
static hasMany = [schools: School]
...

Child class object can not delete

I have some domain class Incident,Problem, Category, Impact, Urgency etc.
Class Incident
{
Category category
String subject
Impact impact
}
Class Problem
{
Urgency urgency
Category category
String title
}
Class Category
{
String categoryName
String description
}
now, some rows are inserted into this class. now if I am deleting category it throws error like 'grails cannot delete or update a parent row'..
so what I have to do for deleting?
The problem is - you have reference to Category in Incident and Problem classes, so database tables for those classes will have Foreign key on category table, so you can not delete a category untill you either remove those incidents/problems or update those incidents problems and set category to null (you will have to make them as nullable in domain constraints)
So either you do
Problem.executeUpdate('update Problem p set category = null where category = ?', [category])
Same for incidents
Or you can model your domain classes using belongsTo and hasMany and grails will handle every thing automatically
Some thing like
class Problem {
static belongsTo = [category:Category]
}
class Category {
static hasMany = [
problems: Problem
]
static mappings = {
problems cascade: "all-delete-orphan"
}
}
I would prefer to manage relationships using belongsTo, hasMany, hasOne rather then just using references, it expresses the model better.
It depends on your domain model as well, in your business can problems, incidents exist without a category ! or they must belong to some category. If your answer is first option, your dont want to cascade delete, but update those incidents/problems with null category, if your answer is second option - you needs cascade all-delete-orphan
How your Category looks like, is it belongsTo Incident domain class,if category belongs to some domain class you can not delete it.
Ref : See here

Access Relationship Table in Grails

I have the following domains classes:
class Posts{
String Name
String Country
static hasMany = [tags:Tags]
static constraints = {
}
}
class Tags{
String Name
static belongsTo = Posts
static hasMany = [posts:Posts]
static constraints = {
}
String toString()
{
"${TypeName}"
}
}
Grails creates an another table in the database i.e. Posts_Tags.
My requirement is:
E.g. 1 post has 3 tags.
So, in the Posts_Tags table there are 3 rows.
How can I access the table Posts_Tags directly in my code so that I can manipulate the data or add some more fields to it.
If you want to access the join table (Posts_Tags) directly, or add properties to it, then you must define it as a separate PostTag domain class. You then split your many-many relationship between Post and Tag into 2 one-to-many relationships (one from Post to PostTag and one from Tag to PostTag).
Here's a comprehensive example of how to perform the mapping and add properties to the join table - in this example Membership is the join table.
Use the normal groovy sql API. For an example of how to get a groovy SQL object and execute sql queries see this

Resources