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 を非常にうまく設定します...しかし、私は MemberRole モデルではなく Role モデルに取り組んでいるので、結合モデルにアクセスして を設定する方法について、ちょっと行き詰まっています:スコープと: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

すべてを 1 つのトランザクションに含めるようにしてください。

他の可能性は、関連付けで使用することaccepts_nested_attributes_forですmember_roles

于 2010-02-17T21:50:21.670 に答える
0

ネストされた属性の使用を検討する必要があるように聞こえます。

于 2010-02-17T18:23:28.843 に答える