Search code examples
grailsgrails-orm

grails - setting up a one to many to one relationship


class Invoice {
   static hasMany = [invoiceItem: InvoiceItem]
}

class InvoiceItem {
   static belongsTo = [invoice: Invoice, item: Item]
   static constraints = {
       invoice(nullable: false)
       item(nullable: false)
   }
}

class Item {
   String name
   static hasMany = [invoiceItem: InvoiceItem]
}

Let's say I already have an Invoice created, I'm not sure how to create a new item and add it to the Invoice.

I was thinking:

Item item1 = new Item(name: "Banana")
InvoiceItem ii = new InvoiceItem(item_id: item1.id)
invoice.addToInvoiceItem(ii);

but that doesn't seem to be working. Any help would be appreciated :)


Solution

  • I dont really understand your comment "There should only be one Invoice and one Item but many InvoiceItems.".

    I dont think that statement is valid because invoiceitem table will have two columns ( item_id and invoice_id) so for one item and one invoice you will have only one invoiceitem row unless you want to have duplicate rows in the invoiceitem, hence not valid.

    So basically you need the middle table invoiceitem means you are having many to many relationship between invoice and item.

    In Grails you do it like this, simple:

    class Invoice {
       static belongsTo = [item: Item]
       static hasMany = [items: Item]
    }
    
    
    class Item {
       String name
       static belongsTo = [invoice: Invoice]
       static hasMany = [invoices: Invoice]
    }
    

    You can change the names items and invoices to whatever you like.

    So when you create the above two domain classes hibernate knows it is many to many relationship, it needs normalization and will automatically create the middle table: invoiceitem or iteminvoice which will contain invoice_id and item_id.

    To add item to invoice:

    invoiceInstance.addToItems(itemInstance)
    

    To add invoice to item:

    itemInstance.addToInvoices(invoiceInstance)