views:

31

answers:

1

I have a model called Purchase and a model called TicketType. A purchase can have many ticket types, and a ticket type can have many purchases.

So I have

class Purchase < ActiveRecord::Base
  has_many :purchases_ticket_types, :class_name => 'PurchaseTicketType'
  has_many :ticket_types, :through => :purchases_ticket_types
end

class TicketType < ActiveRecord::Base
  has_many :purchases_ticket_types, :class_name => 'PurchaseTicketType'
  has_many :purchases, :through => :purchases_ticket_types
end

class PurchaseTicketType < ActiveRecord::Base
  set_table_name "purchases_ticket_types"
  belongs_to :purchase
  belongs_to :ticket_type
end

I knew purchases_ticket_types for a table name was going to be trouble as soon as ActiveRecord failed to identify the correct table name from the camel-cased class name. I ended having to call set_table_name.

But the worst part is having to do this:

purchase = Purchase.find(1)
purchase.purchases_ticket_types.each do |purchase_ticket_type|
  puts 'join contains quantity: ' + purchase_ticket_type.quantity
  puts 'ticket type name is: ' + purchase_ticket_type.ticket_type.name
end

Look how verbose and repetitive that reads. Everything is working but it looks so ugly. Is there a better way of naming many-to-many associations to avoid this kind of thing: purchase.purchases_ticket_types.first.ticket_type.name ?

Thanks!

+2  A: 

How about using TicketSale as the join model name (or simply Sale if your application doesn't sell anything else apart from tickets):

class Purchase < ActiveRecord::Base
  has_many :ticket_sales
  has_many :ticket_types, :through => :ticket_sales
end

class TicketType < ActiveRecord::Base
  has_many :ticket_sales
  has_many :purchases, :through => :ticket_sales
end

class TicketSale < ActiveRecord::Base
  belongs_to :purchase
  belongs_to :ticket_type
end
John Topley
This is a good answer - but I thought I would just chip in that has_and_belongs_to_many can work for these type of relationships too. Here are the docs: http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association
sosborn
@sosborn I used `has_many, :through` because that's what was in the original question, presumably because the original poster requires extra attributes on the join model, which `has_and_belongs_to_many` doesn't support.
John Topley