UnknownAttributeError с использованием сборки для виртуального атрибута
У меня есть вложенная форма, содержащая виртуальные атрибуты: 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'))
но это кажется немного неуклюжим. Есть ли другие способы обойти это?
1 ответ
Сообщение об ошибке "Невозможно массово назначить защищенные атрибуты" - все о защите массовых назначений. Вы можете пройти без_протекции, чтобы игнорировать проверку массового назначения.
@order = @appointment.build_order(params[:appointment]['order'], without_protection: true)
Эта ссылка объясняет, что такое массовое присвоение безопасности. Rails Internals: массовое присвоение безопасности
Если вы хотите указать массовые присваиваемые атрибуты, используйте attr_accessible:one,:another для атрибутов вашей модели. Если вам нужны другие немодельные атрибуты, используйте attr_accessor:card_number, а затем attr_accessible:card_number, чтобы объявить и представить его.
Я вижу, что вы определяете card_number и card_verfication в модели Order, но вы используете form_builder => f для определения этих двух полей в html. Попробуйте вместо этого использовать fields_for builder.