0

我使用 具有典型的多对多关系has_many => :through,如下所述。

class member
  has_many member_roles
  has_many roles, :through => :member_roles
end

class role
  has_many member_roles
  has_man members, :through => :member_roles
end

class member_role
  belongs_to :member
  belongs_to :role
  # has following fields: member_id, role_id, scope, sport_id
end

我在这里尝试做的是允许为成员分配角色。每个成员角色都有一个范围,默认情况下设置为“全部”,但如果需要,可以设置为“运动”。如果范围设置为运动,那么我们还捕获了 sport_id,它允许我们将对该角色的评估限制为特定运动(即,只能管理该运动的团队,而不是每个运动的团队)。听起来很简单。

我已经设置update_member_roles了这样的操作:

def update

  # Assume we passing a param like: params[:member][:roles]
  # as an array of hashes consisting of :role_id and if set, :sport_id

  roles = (params[:member] ||= {}).delete "roles"
  @member.roles = Role.find_all_by_id(roles.map{|r| r["role_id"]})
  if @member.update_attributes params[:member]
    flash[:notice] = "Roles successfully updated."
    redirect_to member_path(@member)
  else
    render :action => "edit"
  end
end

上面的工作很好,它很好地设置了适当的 member_roles ......但是当我正在研究 Role 模型而不是 MemberRole 模型时,我有点卡住了如何访问加入模型来设置:范围和:sport_id。

这里的任何指针将不胜感激。

4

2 回答 2

1

您应该使用member_roles关联而不是roles关联。

  def update
    # The role hash should contain :role_id, :scope and if set, :sport_id
    roles = ((params[:member] ||= {}).delete "roles") || []
    MemberRole.transaction do 

      # Next line will associate the :sport_id and :scope to member_roles
      # EDIT: Changed the code to flush old roles.
      @member.member_roles = roles.collect{|r| MemberRole.new(r)}

      # Next line will save the member attributes and member_roles in one TX
      if @member.update_attributes params[:member]
        # some code
      else
        # some code
      end
    end
  end

确保将所有内容都包含在一个事务中。

其他可能性是用于accepts_nested_attributes_for关联member_roles

于 2010-02-17T21:50:21.670 回答
0

听起来您应该考虑使用嵌套属性:

于 2010-02-17T18:23:28.843 回答