我有一个典型的许多对多关系使用 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非常漂亮...但是为我工作上的作用的模式并不MemberRole模型我卡住了如何我可以访问的参加模型设定的范围,并且:sport_id.

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

有帮助吗?

解决方案

您应该使用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

其他提示

听起来像是你应该看看使用嵌套的属性:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top