So essentially I have two classes:
Class User {
String Name
}
Class Project {
User requestedBy
static hasMany =
[
assignedTo: User
]
}
Now, I can set the requestedBy to say, User 1.
I can also do Project.addToAssignedTo(User 1).
The problem comes when I want to remove the user from assigned to when they already exist as the requestedBy. I can remove other users without problem:
Project.removeFromAssignedTo(User 1).save(failOnError: true, flush: true)
I get no errors of any kind, the data just simply does not get removed. Any help would be appreciated!
Thanks!
When defining multiple relationships to the same class, you should define the bidirectional relationship, and use the mappedBy property to define both sides of that relationship:
class User {
String Name
hasMany = [requestedProjects: Project, assignedProjects: Project]
}
class Project {
User requestedBy
static hasMany =
[
assignedTo: User
]
static mappedBy = [requestedBy: 'requestedProjects', assignedTo: 'assignedProjects']
}
Hopefully that solves your problem.
Related
I would like to, whenever a domain is deleted, delete all hasMany domains and associated domains. I have the following domain structure.
class Book {
static hasMany = [ bookOptions: BookOption ]
}
class Category {
static hasMany = [ options: Option ]
static mapping = {
options cascade: "all-delete-orphan"
}
}
class Option {
static belongsTo = [ category: Category ]
}
BookOption {
Option option
static belongsTo = [ book: Book, category: Category ]
}
I would like to delete all options, bookOptions and remove associations between Book and BookOption whenever a Category is deleted.
Currently with options cascade: "all-delete-orphan", all options are deleted when a Category is deleted, however I encounter a referential integrity constraint violation to BookOption.
An option would be to manually find all bookOptions, iterate over the list and delete each one.
def bookOptions = BookOption.findAllByCategory(category)
bookOptions.each{ bookOption ->
def book = bookOption.book
book.removeFromBookOptions(bookOption)
bookOption.delete(flush:true)
}
category.delete(flush:true)
Is there a more of a Grails way of performing this operation? Or is the option I defined the standard?
I think there should be hasMany bookOptions in Category. Please check whether the tables created are MyISM or InnoDB.
def books = Books.findAllByCategories(category)
books?.each{ book ->
book?.categories?.clear()
book?.bookOptions?.clear()
}
I am new to grails and still trying to wrap my head around the mapping of objects. In our project we have three classes that are causing some problems Attendee, Vendor, and Person An attendee has one person and a vendor has many persons so we went with the following setup:
class Person{
String firstName
//Other details...
}
class Attendee {
Person person
}
class Vendor{
static hasMany = [
person:person
]
}
So the objects are being hydrated via a web form and I can confirm that the person details are being hydrated from a log statement. However we get the following error:
Message ORA-01400: cannot insert NULL into ("EIGHT_STATES_USER"."ATTENDEE"."PERSON_ID")
so we added static belongsTo = [attendee: Attendee, vendor: Vendor] to our Person based on a stackoverflow we read. But then when we tried to save the Attendee it wanted to create a Vendor.
Not sure where to go from here.
Try adding a mapping to your Attendee object:
Person person
static mapping = {
person cascade: "all"
}
More information about the custom mapping can be found here: http://grails.org/doc/2.3.x/guide/GORM.html#customCascadeBehaviour
The way you currently have it defined, you need to save the Person object first and then add it to the Attendee and save. You don't need the belongsTo in Person.
class Person {
String firstName
//Other details...
}
class Attendee {
Person person
}
class Vendor {
static hasMany = [
people:Person
]
}
def person = new Person(params)
if (person.save(flush:true)) {
def attendee = new Attendee(params)
attendee.person = person
attendee.save(flush:true)
}
Given the following User class:
class User {
String name
static hasMany = [friends: User]
}
I want that a User can have many friends which are instances of the user domain class.
How do I have to implement the friend relationship of a user?
1. How Do you Define the relathionship
class User {
static hasMany = [ friends: User ]
static mappedBy = [ friends: 'friends' ] //this how you refer to it using GORM as well as Database
String name
String toString() {
name
}
def static constrains () {
name(nullable:false,required:true)
}
def static mapping={
/ / further database custom mappings ,like custom ID field/generation
}
}
2.How to save Data:
def init = {servletContext->
if(User?.list()==null) { // you need to import User class :)
def user = new User(name:"danielad")
def friends= new User(name:'confile')
def friends2=new User(name:'stackoverflow.com')
user.addToFriends(friends)
user.addToFriends(friends2)
user.save(flash:true)
}
}
3# . Your question is repeated on this stack overflow link :
Maintaining both sides of self-referential many-to-many relationship in Grails domain object
It looks like many-to-many relationship (one user has a lot of friends, and is a friend of a lot of users). So one of the solution will be to create new domain class, lets say it Frendship. And then modify User domain class like here:
class Friendship {
belongsTo = [
friend1: User
, friend2: User
]
}
class User{
String name
hasMany = [
hasFriends: Friendship
, isFriendOf: Friendship
]
static mappedBy = [
hasFriends: 'friend1'
, isFriendOf: 'frined2'
]
}
Here I am facing an unusual issue. Everything should work in my understanding (as a grails beginner), but not working :(
I have a domain class User. User can have many friends and many friendRequests. There is a function in domain class to send friend request to other user. here is the code from User Domain -
static hasMany = [friends: User, friendRequests: FriendRequest]
static mappedBy = [friendRequests:'receiver']
def sendFriendRequest(User toUser) {
if(!isFriend(toUser)) {
FriendRequest requestToSend = new FriendRequest(status:'pending', sender: this)
toUser.addToFriendRequests(requestToSend)
return true
}
return false
}
And the FriendRequest class is -
class FriendRequest {
String status
User sender
static constraints = {
status(inList:["accepted", "pending", "rejected"])
}
static belongsTo = [receiver:User]
}
Now, The problem is, I am expecting the current User object, from which I am running the function will be set as sender of friendRequest. But strangely the toUser, which I m passing as param is being set as sender!
Can anyone please explain what I am missing?
The addToFriendRequests method is overriding sender. It thinks that FriendRequest.sender is the inverse of User.friendRequests
Your FriendRequest class will need two references to User: one for the sender, and one for the receiver. You'll also need to tell gorm which one maps back to the friendRequests relationship. You can do this with a mapping in your User class:
static mappedBy = [friendRequests:'receiver']
I have a User domain class, and a List one.
Each list must have an author (a user) and each user must have a "primary list". Only some of the lists will have the "primaryList" statute.
So.. somthing like
User:
List primaryList
List:
User author
static belongsTo = User
Of course this does not work as intended because the two relations are mistakenly taken as only one. I should also add a hasMany on the User and other belongsTo to the List..., but I don't want to complicate the example because I want to get the right answer from you.
You may need to use mappedBy to explain how the fields in User and List line up. Here are a couple domains that I wrote that allow a User to author many Lists but only set one to be "primary". There are a couple extra nullable constraints so you can use the scaffolded UI without getting into a chicken-and-egg scenario.
class User {
String name
FooList primaryList
static hasMany = [authoredLists: FooList]
static mappedBy = [primaryList: 'primaryOwner', authoredLists: 'author']
static constraints = {
primaryList nullable: true, unique: true
authoredLists nullable: true
}
String toString() { name }
}
I named this class "FooList" just to avoid confusion with the standard List class:
class FooList {
static belongsTo = [author: User, primaryOwner: User]
static constraints = {
primaryOwner nullable: true, display: false
}
}
Try using the map belongsTo approach:
static belongsTo = [user:User]
That way Grails should see the 2 properties as separate.