0

我有一個嵌套的窗體包含虛擬屬性:card_number和:card_verification。當我嘗試在控制器更新操作中使用這些操作時,我得到ActiveRecord :: UnknownAttributeError。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當我嘗試subm它的更新,與參數:

{"utf8"=>"✓", 
"_method"=>"put", 
"authenticity_token"=>"KowchWLNmD9YtPhWhYfrNAOsDfhb7XHW5u4kdZ4MJ4=", 
"appointment"=>{"business_name"=>"Name", 
"contact_method"=>"Phone", 
"contact_id"=>"555-123-4567", 
"order"=>{"email"=>"[email protected]", 
"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

錯誤消息「無法批量分配受保護的屬性」全是關於批量分配安全性。您可以傳遞without_protection忽略質量分配檢查。

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

此鏈接解釋什麼是質量分配安全。 Rails Internals: Mass Assignment Security

如果要指定可分配質量的attrs,請爲模型屬性使用attr_accessible:one::another。 如果您需要其他非模型屬性,請使用attr_accessor:card_number,然後使用attr_accessible:card_number聲明並公開它。

我看到你在Order模型中定義了card_number和card_verfication,但是你使用form_builder => f來在html中定義這兩個字段。改爲使用fields_for生成器。

+0

感謝您的想法。如果可能,我寧願避免繞過Rails安全措施的習慣;我希望有一種方法可以允許我想要的屬性(card_number&card_verification)的質量分配,而不是忽略所有屬性。 – tyler