如何在rails中建立多对多的关系

时间:2012-04-21 13:59:02

标签: ruby-on-rails migration associations has-and-belongs-to-many

我是rails的新手,我正在尝试在rails项目中建立多对多的关系。我有一个小策略,但我不确定它是否正确。

目的: 我有一个用户表和一个组表。用户可以是许多组的一部分,每个组可能有许多用户。

策略

  1. 将用户迁移设置为名称:string
  2. 将组迁移设置为名称:string
  3. 设置加入表迁移
  4. 设置用户模型,使其具有has_and_belongs_to_many:groups
  5. 设置群组模型,使其具有has_and_belongs_to_many:users
  6. 这是正确的策略吗?谢谢!

    来自回答的铁路广播摘要 对于那些感兴趣的人 - Railcast建议你使用has_many:通过关联,因为上面的策略有限制,你不能添加额外的关系特定信息。

    结帐:http://kconrails.com/tag/has_many/

2 个答案:

答案 0 :(得分:16)

首先,我假设您有一个带有“name”字段的用户模型和一个带有“name”字段的组模型。

您需要在用户和群组之间使用模型。我们称之为分组:

rails g model grouping user_name:string group_name:string

在分组模型(grouping.rb)中,您输入:

belongs_to :user  
belongs_to :group

在用户模型中:

has_many :groupings, :dependent => :destroy
has_many :groups, :through => :groupings

在小组模型中:

has_many :groupings, :dependent => :destroy  
has_many :users, :through => :groupings

在_form文件中编辑或更新用户的个人资料,请输入:

<div class="field">
    <%= f.label :group_names, "Groups" %>  
    <%= f.text_field :group_names %>  
</div>

最后,用户类必须知道如何处理表单中的信息。插入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删除所有单词的空白和下行,因此您不会有冗余标记。

现在,您可以在他或她的个人资料的show文件中显示用户的群组:

<p>Groups:
  <% @user.groups.each do |group|%>
    <%= group.name %>
   <% end %>
</p>

希望,这有帮助。

答案 1 :(得分:3)

好消息是,这已经有了很好的记录。

Ruby on Rails Guide

Railscast tutorial