i have two domain : User and Task such as :
1) a user can be the author of many tasks
2) a user can participate in many tasks,in the same time,a task can have many users which participate in
so,i want to define a one-to-many for 1) and a many-to-many for 2)
User{
static hasMany = [createdTasks : Task, //for one-to-many
assignedTasks : Task //for many-to-many
]
static mappedBy = [createdTasks : author]
}
Task{
User author
static hasMany = [assignedUsers : User]// for many-to-many
}
i think i have to define the owner side of my many-to-many relationship(assignedTasks-assgnedUsers)
?
anyone have a idea for defining the correct relationship satisfying my specification 1) and 2)?
thanks :)
I think you could accomplish this an easier way:
Really the relationships can just be on the task. The only reason to do what you are trying to do is to create a bi-directional relationship. This can be achieved simpler with declaring methods on the user to get the objects you want.
User{
Set<Task> getCreatedTasks() {
Task.findAllByAuthor(this)
}
Set<Task> getAssignedTasks() {
Task.executeQuery("""
Select t
from Task t join t.assignedUsers as tu
where tu = :user
""", [user: this])
}
}
Task{
User author
static hasMany = [assignedUsers : User]
}
Try this. Note the quotation in mappedBy.
User {
static hasMany = [
createdTasks: Task, // for one-to-many
assignedTasks: Task // for many-to-many
]
static mappedBy = [
createdTasks: 'author'
]
}
Task {
User author
static hasMany = [
assignedUsers: User // for many-to-many
]
static belongsTo = [
User
]
}
Related
I have two tables Users and Role
These two tables should have bi-directional relationship for security purposes, so I have followed hasOne combination in Users table and belongs to in Role table. But bi-directional relationship is not happening.
Can anyone please help in this ?
class User
{
Long number
Integer inhabitants
static hasOne = [ role: Role]
static constraints = {
role nullable: true, unique: true
}
}
class Role
{
Users user
static belongsTo = [user: Users ]
static constraints = {
}
}
Change Role to
class Role
{
Users user
static belongsTo = [user: User ] //you previously had Users here
static constraints = {
}
}
I use Grails Plugin spring-security-core and these two pages to help me setup.
Simplified Spring Security with Grails and
Tutorials - Reference Documentation.
It creates a table called UserRole that takes care of all that.
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()
}
My project requires me to maintain the insertion and retrieval order in a many-many relationship. By default, groovy saves the elements as a Set in many-many relationship. I want to do it in a List. I am not sure how to update the relationship to use List instead of Set. Any help would be appreciated.
class Course{
static belongsTo = Teacher
static hasMany = [teacher:Teacher]
static mapping = {
teacher joinTable : [name: TeacherCourse]
}
}
class Teacher{
static hasMany = [course:Course]
static mapping = {
course joinTable : [name: TeacherCourse]
}
}
save() call on either Teacher or Course also inserts a new row in TeacherCourse table. It works with no issues. In Database there the tables are:-
Teacher (PK: Id)
Course (PK: Id)
TeacherCourse(PK: [Teacher_id,Course_id])
Is there a way I can maintain the order of insertion and retrieval in many-many relationship?
Thank you..
Edit
In controller save()
def courseInstance = new Course()
List <Teacher> teacherList= []
teacherList.add(Teacher.findById(65))
teacherList.add(Teacher.findById(36))
courseInstance.courseUnits = teacherList
courseInstance.save(flush:true)
Try this:
class Course {
List teachers
static belongsTo = Teacher
static hasMany = [teachers:Teacher]
static mapping = {
teachers joinTable : [name: TeacherCourse]
}
}
class Teacher {
List courses
static hasMany = [courses:Course]
static mapping = {
courses joinTable : [name: TeacherCourse]
}
}
Reference
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'
]
}
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.