2

Warehouseモデル、モデルCar、およびモデルがあるとしましょうDealer

モデルCarは次のようなものです:

attr_accessible :make, :year
belongs_to :warehouse
belongs_to :dealer

コントローラーCarsは次のようなものです:

def create
  car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params[:car])
  car.save!
end

のビューCars#newは次のようになります。

<%= semantic_form_for @car do |f| %>
  <%= f.inputs do %>
    <%= f.input :warehouse, :include_blank => false %>
    <%= f.input :make %>
    <%= f.input :year %>
  <% end %>
<% end %>

ディーラーは車を追加する際に倉庫を選択できます. 上記のコードは大量割り当てから保護されています. (つまりディーラーが所有していない倉庫に車を追加します.):warehouse_id , しかし, 大量割り当てはできないという例外が発生します.あまりにもparams[:car][:warehouse_id]

手動で属性を割り当てずにそのエラーを取り除く方法は? とにかくそれは良い方法ですか?

PS私は試しparams[:car].delete(:warehouse_id)ましたが、これを行う正しい方法のようには見えません。

4

3 に答える 3

2

:warehouse_id は車の一括割り当て可能な属性ではないため、フォームから車の属性として投稿することはできません。コントローラーで何もしていなくても、そのような方法でパラメーターに名前を付けると、Rails は大量割り当てエラーを発生させます。

するのではなく(非形式固有):

<%= f.hidden_field :warehouse_id %>

行う:

<%= hidden_field_tag :warehouse_id, @car.warehouse_id %>

私は formtastic にあまり詳しくありませんが、上記の行は機能すると思います。

コントローラーで:

def create
  @car = current_dealer.find(params[:warehouse_id]).cars.new(params[:car])
  @warehouse = Warehouse.find(params[:warehouse_id])
  @car.warehouse = @warehouse
  @car.save!
end

それはもう少し退屈です、私は知っています。残念ながら、コードを保護するには、さらに努力が必要です。

結論: params[:car][:warehouse_id]= 質量割り当て

于 2012-07-01T19:47:38.523 に答える
1

attr_accessible の使用をやめ、strong_parameters を使用してください

削除するattr_accessible :make, :year

gem 'strong_parameters'Gemfileに追加します。

各モデルに追加include ActiveModel::ForbiddenAttributesProtectionします。

次に、次を置き換えます。

car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params[:car])

と:

car = current_dealer.find(params[:car][:warehouse_id]).cars.new(params.require(:car).permit([:make, :year]))
于 2012-08-18T06:37:45.330 に答える
0

一括割り当ては、フォーム (または API) を介してフィールドを設定できるかどうかのみを決定し、何を設定できるかは制御しません。問題は、大量割り当てを使用してデータの検証または制限を制御しようとしていることです。あなたの場合warehouse_id、ユーザーが選択したピックリストを介して保存できるようにしたいため、車を作成するための標準のパラメーターアプローチを使用するには、一括割り当てが可能でなければなりません。

推奨される解決策は、最初に Formtasticselect入力を使用して、ディーラーが選択できる値を制限することです。現在倉庫をどのように制限しているかはわかりませんが、一般的なバージョンは次のとおりです。

f.input :warehouse, :as => :select, :collection => "Whatever your selection rule is"

これにより、ディーラーが利用できる倉庫のリストのみが実際にフォームに表示されるようになります。

これは、十分な技術的知識を持つ人が URL の Warehouse_id を変更し、所有していないウェアハウスに投稿する可能性があるという問題を解決しません。そのため、ディーラーに属する倉庫のみが有効な選択であることを保証する検証を Car モデルにも追加する必要があります。

これで問題が解決し、必要な Warehouse_id の一括割り当てをそのままにして、ディーラーが自分に属する倉庫のみを選択できるようにします。

于 2012-07-02T13:50:54.470 に答える