I have two tables with a many to many relationship that I am using has_and_belongs_to_many to define the association.
class Foo < ActiveRecord::Base
...
has_and_belongs_to_many :bar
...
end
class Bar < ActiveRecord::Base
...
has_and_belongs_to_many :foo
...
end
I also have the class defined to represent the join table
class BarFoo < ActiveRecord::Base
...
belongs_to :foo
belongs_to :bar
...
end
When I run rake db:seed I get the following error:
Primary key is not allowed in a has_and_belongs_to_many join table (bar_foo)
If I edit the database and remove the primary key field (ID) from the bar_foo table and then rerun rake db:seed everything works as desired.
Given the above, what is the preferred means of creating join tables in rails with no primary key?
I also tried using "has_many :bars, :through => :foo" and vise versa but got an error message something like "undefined method 'klass' for nil:NilClass".
Yes, you can! The longer answer is yes, there are a few ways to combine two tables without a common column, including CROSS JOIN (Cartesian product) and UNION. The latter is technically not a join but can be handy for merging tables in SQL. In this article, I'll guide you through the different solutions with examples.
A declared foreign key relationship is not necessary for using join . Foreign keys are not needed to join tables!
A primary key is a value that cannot be duplicated within a table. This means that one value can only be seen once within the primary key column.
You don't need the model
class BarFoo < ActiveRecord::Base
...
belongs_to :foo
belongs_to :bar
...
end
the has_and_belongs_to_many
association will search for a table called bar_foo
in your database what you need to do is generate a migration to create this table.
rails generate migration add_table_bar_foo_for_association
then you edit your migration and it should look like this
class AddTableBarFooForAssociation < ActiveRecord::Migration
def up
create_table :bar_foo, :id => false do |t|
t.references :bar
t.references :foo
end
end
def down
drop_table :bar_foo
end
end
Now your association should work and also if you need the association to have extra attributes on the join you can use the has_many :through
way and create a model associated to this.
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