views:

40

answers:

2

this has been bugging me,

lets say i have two model, category and product

class Category {
  static hasMany = [products : Product]
  String name
}
..
class Product {
  String name
}

now, i want to delete product, which happens to exist in many category. i came up with these lines in my product beforeDelete methods

def beforeDelete = {
  Category.list()?.each{
       it.removeFromProducts(this)
    }
}

now this may works, but the way i see it, thats a lots of query for one simple task. i know i can get the same result just with a single line of sql string ("delete from category_product where product_id = ?"). but im just curious, is there more sophisticated way to achieve this in grails? (besides executing the sql string)

A: 

This is not a one-to-many relationship, is a many-to-many if a product is in many categories and a category has many products. If it is a one-to-many, the problem doesn't exist.. you delete category and all the products related are deleted and if you delete a product is just that product that is deleted

Ben
A: 

You could add the following lines to the Category class

static mapping = {
    products cascade: "all-delete-orphan"
}

and call delete on Category instead. Why are you using a unidirectional relation in this case? Wouldn't it be better with a bi-directional one? In the case above you iterate over all Categories each time you delete a Product which is a resource heavy operation (depending on you many categories you have of course), the better solution would be to find the Category via a bi-directional relation like this:

class Product {
    String name
    static belongsTo = [category: Category]
}

That was you can easily get to Category from Product and delete it.

See this blog post on more hints and tips.

Mr.B