0

仮想属性 :card_number と :card_verification を含むネストされたフォームがあります。コントローラーの更新アクションでこれらを使用してビルドしようとすると、ActiveRecord::UnknownAttributeError が発生します。

モデルには単純な has_one 関係があり、予定には has_one オーダーがあります

#/models/appointment.rb
class Appointment < ActiveRecord::Base
  has_one :order
  accepts_nested_attributes_for :order

  attr_accessible (...)
end

#/models/order.rb
class Order < ActiveRecord::Base
  belongs_to :appointment

  attr_accessible :email, (...)
  attr_accessor :card_number, :card_verification
end

私はこのようなフォームを生成しています:

# /views/appointments/edit.html.erb
<%= form_for @appointment do |f| %>
  ...
  <%= f.fields_for @appointment.order do |builder| %>
    <%= builder.label :email %>
    <%= builder.text_field :email %> # works fine on its own
    ...
    <%= f.label :card_number %>
    <%= f.text_field :card_number %>

    <%= f.label :card_verification %>
    <%= f.text_field :card_verification %>
  <% end %>
  ...
<% end %>

そして、コントローラーを構築します:

# /controllers/appointments_controller.rb
def update
  @appointment = Appointment.find(params[:id])
  @order = @appointment.build_order(params[:appointment]['order']) # This line is failing

  if @appointment.update_attributes(params[:appointment].except('order'))
    # ... Success
  else
    # ... Failure
  end
end

Can't mass-assign protected attributes: card_number, card_verificationこれにより、更新のために送信しようとすると、パラメーターを使用してエラーが発生します。

{"utf8"=>"✓",
 "_method"=>"put",
 "authenticity_token"=>"KowchWLNmD9YtPhWhYfrNAOsDfhb7XHW5u4kdZ4MJ4=",
 "appointment"=>{"business_name"=>"Name",
 "contact_method"=>"Phone",
 "contact_id"=>"555-123-4567",
 "order"=>{"email"=>"user@example.com",
 "first_name"=>"John",
 "last_name"=>"Doe",
 "card_number"=>"4111111111111111", # normally [FILTERED]
 "card_verification"=>"123", # normally [FILTERED]
 "card_type"=>"visa",
 "card_expires_on(1i)"=>"2015",
 "card_expires_on(2i)"=>"11",
 "card_expires_on(3i)"=>"1",
 "address_line_1"=>"123 Main St",
 "address_line_2"=>"",
 "city"=>"Anywhere",
 "state"=>"CA",
 "country"=>"USA",
 "postal_code"=>"90210"}},
 "commit"=>"Submit",
 "id"=>"2"}

:card_number と :card_verification の値がフォームに含まれていなくても、すべて正常に機能します。

ここで何がうまくいかないのか誰か知っていますか?

編集:

私はこれを働かせることができます:

@order = @appointment.build_order(params[:appointment]['order'].except('card_number', 'card_verification'))

しかし、これは少し不格好に思えます。これを回避する他の方法はありますか?

4

1 に答える 1

1

「保護された属性を一括割り当てできません」というエラーメッセージは、すべて一括割り当てセキュリティに関するものです。without_protectionに合格すると、一括割り当てチェックを無視できます。

@order = @appointment.build_order(params[:appointment]['order'], without_protection: true)

このリンクは、一括割り当てセキュリティとは何かを説明しています。 Rails Internals:一括割り当てセキュリティ

一括割り当て可能な属性を指定する場合は、モデル属性にattr_accessible:one、:anotherを使用します。他の非モデル属性が必要な場合は、attr_accessor:card_numberを使用してから、attr_accessible:card_numberを使用して宣言し、公開します。

Orderモデルでcard_numberとcard_verficationを定義しているようですが、form_builder=>fを使用してhtmlでこれら2つのフィールドを定義しています。代わりにfields_forbuilderを使用してみてください。

于 2012-11-01T06:31:59.003 に答える