1

私はPeepCodeの (現在は少し古い) Meet Rails 3チュートリアルに従っていますが、チュートリアルのいくつかの提案を Rails 3.2 と連携させるのに苦労しています。

チュートリアルでは、以下Roleに属するモデルを作成しProjectます。

class Role < ActiveRecord::Base
  belongs_to :project
  validates :project_id, :presence => true
  attr_protected :project_id
end

routes.rbファイルは、 のコンテキストで を操作Roleする必要があるように、リソースをネストします。RoleProject

resources :projects do
  resources :roles
end

上記のモデル コードでは、プロジェクトのコンテキストでevery を作成することで「より安全に」設定できるため、フィールドattr_protectedを保護するために使用するようにチュートリアルでアドバイスされていることに注意してください。:project_idRole

class RolesController < ApplicationController
  ⋮

  def create
    @role = project.roles.new(params[:role])
    ⋮

問題は、 FormtasticRoleで作成された を作成するための HTML フォームに、プロジェクトを選択するためのフィールドが含まれていることです。したがって、フォームからのパラメーターを使用して新しいオブジェクトを設定しようとすると、質量割り当てを使用して設定しようとし、次のように失敗します。project_idproject.roles.new(params[:role])Roleproject_id

ActiveModel::MassAssignmentSecurity::RolesController#create のエラー
保護された属性を一括割り当てできません: project_id

これを実装するために受け入れられている方法は何ですか? 属性を保護するproject_idことは悪い考えでしたか? または、を含めずに新しいRoleフォームデータを入力する方法はありproject_idますか?

4

1 に答える 1

0

とにかく実際に競合する値を設定している可能性があるのではなく、project経由している場合。params[:project_id]params[:role][:project_id]

Mass Assignment がこれを保護する理由は、ユーザーが任意の値を入力して、このユーザーの制御下にない をproject_id許可するのを防ぐためです。projectいくつかのオプションがあります。

オブジェクトに権限があるuserかアタッチされている場合は、 などaccountのコールバックに追加できます。before_saveself.project_id = nil unless user.projects.find(project_id)

そうでないので、私project_idはプロジェクトを見つけるためにハッシュからを使用し、ルート ID にフォールバックします (それがそうであるproject_idか、それともid私の頭のてっぺんから離れているかはわかりません)。

def create
  user.
    projects.
    find(params[:role].delete(:project_id) || params[:project_id] || params[:id]).
    create(params[:role])

最も簡単な方法は、フォームから選択ボックスをドロップすることです。これは、新しい役割を作成することを選択したときにプロジェクトを選択したためです。これはネストされたリソースです。

于 2013-01-31T06:50:25.703 に答える