I have a User
and MeetOption
table. This is a many-to-many relationship, and I was able to create a join table using the create_join_table command:
rails g migration CreateJoinTableUsersMeetOptions users meet_options
This generated a migration file:
class CreateJoinTableUsersMeetOptions < ActiveRecord::Migration[5.0]
def change
create_join_table :users, :meet_options do |t|
# t.index [:user_id, :meet_option_id]
# t.index [:meet_option_id, :user_id]
end
end
end
I also created the association between user and meet_option models using has_and_belongs_to_many
class User < ActiveRecord::Base
has_and_belongs_to_many :meet_options
#More codes below
end
class MeetOption < ApplicationRecord
has_and_belongs_to_many :users
end
The association works fine, and I can query for example, user.meet_options
in Rails console.
My question is: there is no model for the joined MeetOptionsUsers
table, so how can I add records to it? Right now, I have to manually add rows, i.e. user_id = 1; meet_option_id = 2
, using a GUI database software (Postico).
Is there a way to add records such as MeetOptionUser.create(user_id: 1, meet_option_id: 2)
in Rails console, just like when there's an ActiveRecord model associated with it?
With a has_and_belongs_to_many
relationship, you should be able to use normal Active Record association methods to link your Users
and MeetOptions
together. You should not need to manipulate the join table directly. Rails takes care of that for you. The Ruby on Rails Guide has_and_belongs_to_many Association Reference lists all of the useful methods automatically created by this association.
Here are some methods you may find useful.
The collection<<(object,..)
will add one or more objects to the join table. For example:
@user.meet_options << @meet_option
The above will associate provided @meet_option
record with @user
by adding the appropriate entry in the join table. In this case, a record with user_id: @user.id
and meet_option_id: @meet_option.id
will be added to the join table. The reverse accomplishes the same thing:
@meet_option.users << @user
Another useful method is collection.delete(object,...)
. This allows you to remove associations from the join table. It does not delete the associated objects. For example:
@user.meet_options.delete @meet_option
The above will remove the association between @user
and @meet_option
by deleting the appropriate record from the join table. However, it does not delete @user
from the users
table, nor does it delete @meet_option
from the meet_options
table.
collection.destroy(object,...)
does pretty much the same thing as collection.delete(object,...)
.
collection=(objects)
will make the collection contain only the supplied objects by adding or deleting from the join table as required.
There are many other using methods in this association. I recommend reviewing the linked guide. Using these methods, you should be able to manage the join table without manipulating it directly. Let Rails and Active Record do the work for you.
Final Thought
If you want to have more direct access to the join table via a join model, the you should not use the has_and_belongs_to_many
association. Perhaps you want to add more attributes to your join table or you want to have validations or callbacks on the join model itself. In this case, you should use a has_many :through association instead. This blog post walks through how to set that up.
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