What I mean is if I have two models, connected by a has_and_belongs_to_many association, can I store other data in the join table for each association? That is, the extra data would not be part of a single record in either table, but instead of the connection between them.
My actual models are as follows:
class Part < ActiveRecord::Base
has_and_belongs_to_many :assemblies
has_and_belongs_to_many :packages
belongs_to :user
validates :name, :user_id, :presence => true
end
class Package < ActiveRecord::Base
has_and_belongs_to_many :parts
belongs_to :user
end
So the point is that each part is available in many packages, and each package has different parts. What I want to add is a quantity. That would not be quantity of each part, but of each package of each part.
I can't find how to do this in ActiveRecord. If I was not using rails/activerecord, I'd just add a quantity column to the join table which relates parts to packages. I could obviously make this change in a migration, but how would I access the value using ActiveRecord?
Short answer no you cannot with a HABTM relationship. It is only intended for simple many to many relationships.
You will need to use a has_many :through relationship. In this scenario you will create a join model (PartPackage) where you can define the extra attributes that you need.
class Part < ActiveRecord::Base
has_many :part_packages
has_many :packages, :through => :part_packages
has_and_belongs_to_many :assemblies
belongs_to :user
validates :name, :user_id, :presence => true
end
class PartPackage < ActiveRecord::Base
belongs_to :part
belongs_to :package
end
class Package < ActiveRecord::Base
has_many :part_packages
has_many :parts, :through => :part_packages
belongs_to :user
end
There is a key difference between has_many :through
and has_and_belongs_to_many
the Rails guide explains the differences between the two options in greater detail, however if you want to add data that describes the relationship then use has_many :through
and you can access the model that joins the two.
This is what has_many :through looks like:
Actually, this is possible.
1) Add a quantity key to the packages_parts join table
2) Add this to your Part model
has_and_belongs_to_many :packages, -> { select("packages.*,
packages_parts.quantity") }
Now you can do part.packages[0].quantity
, for example.
What this does is tell Rails to fetch the quantity key whenever it gets the packages for a specific part.
(You can do the same for your Package model if you want to do package.parts.first.quantity as well - just put this on the Package model also, replacing 'packages' with 'parts')
More info: https://ducktypelabs.com/using-scope-with-associations/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With