I am new to rails, and am trying to set up a many-to-many relationship in my rails project. I have a small strategy, but I am not sure if its the correct way.
Aim: I have a table of users, and a table of groups. Users can be part of many groups, and each group may have many users.
Strategy:
Would this be the correct strategy? Thanks!
Railcast Summary from answer: For those that are interested - Railcast suggests you to use a has_many :through association since the strategy above has the limitation that you cannot add extra relation-specific information.
check out: http://kconrails.com/tag/has_many/
First, I assume, you have a user-model with a field "name" and a group-model with a field "name".
You need a model between users and groups. Let's call it grouping:
rails g model grouping user_name:string group_name:string
In the grouping-model (grouping.rb), you put:
belongs_to :user
belongs_to :group
In the user-model:
has_many :groupings, :dependent => :destroy
has_many :groups, :through => :groupings
And in the group-model:
has_many :groupings, :dependent => :destroy
has_many :users, :through => :groupings
In the _form file to edit or update a user's profile, you put:
<div class="field">
<%= f.label :group_names, "Groups" %>
<%= f.text_field :group_names %>
</div>
And, finally, the User-class must know, what to do with the information from the form. Insert into user.rb:
attr_writer :group_names
after_save :assign_groups
def group_names
@group_names || groups.map(&:name).join(' ')
end
private
def assign_groups
if @group_names
self.groups = @group_names.split(/\,/).map do |name|
if name[0..0]==" "
name=name.strip
end
name=name.downcase
Group.find_or_create_by_name(name)
end
end
end
assign_groups removes whitespace and downcases all words, so you won't have redundant tags.
Now, you can show the groups for a user in the show file of his or her profile:
<p>Groups:
<% @user.groups.each do |group|%>
<%= group.name %>
<% end %>
</p>
Hope, that helps.