Rails fields_for 并且未与嵌套对象建立关系
Rails fields_for and not creating relationship with nested object
模型 "Formula" 有许多 "Operands" 使用 simple_nested_form 创建,使用字段。看来流程是正确的,启动没有错误,但是操作数没有保存。
公式模型:
class Formula < ActiveRecord::Base
attr_accessible :name, :client_id
validates_presence_of :name, :client_id
belongs_to :client
has_many :operands, as: :operation, dependent: :destroy
accepts_nested_attributes_for :operands, allow_destroy: true
attr_accessor :operator, :numeric_operand, :operation_id, :operation_type
end
运算模型:
class Operand < ActiveRecord::Base
attr_accessible :operator, :numeric_operand, :operation_id, :operation_type
validates_presence_of :operator
belongs_to :operation, polymorphic: true
OPERATOR_TYPES = ["+", "-", "*", "/"]
end
公式控制器:
class FormulasController < ApplicationController
load_and_authorize_resource
def new
@formula.operands.build
end
def create
@formula = Formula.new(params[:formula])
@formula.client_id = @current_client.id unless @formula.client_id.present?
if @formula.save
redirect_to @formula, notice: t('controllers.notice.successfully_created') }
else
render action: "new"
end
end
def edit
end
def update
if @formula.update_attributes(params[:formula])
redirect_to @formula, notice: t('controllers.notice.successfully_updated')
else
render action: "edit"
end
end
公式_表格:
= simple_nested_form_for @formula, :html => { :class => 'form-vertical' } do |f|
= f.error_notification
.form-inputs
.row
.span3= f.input :name
.well
= f.fields_for :operands
= f.link_to_add t('helpers.links.add'), :operands
.form-actions
= f.button :submit, :class => 'btn-primary', disable_with: "#{t('helpers.links.submitting')}"
_operands_fields:
.well
.row
.span2= f.input :operator, collection: Operand::OPERATOR_TYPES
.span3= f.input :numeric_operand
这一切似乎工作正常,但是当进程结束时,没有创建操作数。在使用更好的错误检查更新或创建方法中返回的参数时,从表单中成功检索操作数属性,但未创建公式与它们之间的关系:
>> @formula.operands.all
=> #<ActiveRecord::AssociationRelation []>
>> @formula.operands.first
=> nil
>> params
=> {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"--TOKEN--", "formula"=>{"name"=>"Sdfg", "operands_attributes"=>{"1457352032591"=>{"operator"=>"+", "numeric_operand"=>"3"}}}, "commit"=>"Update Formula", "action"=>"update", "controller"=>"formulas", "locale"=>"en", "id"=>"3"}
>>
更新(使用强参数)
继续我们的讨论,即 protected_attributes
不适用于 Rails 4(未验证)中的多态关联的嵌套属性,然后我建议使用强参数:
class FormulasController < ApplicationController
# ..
def formula_params
params.require(:formula).permit(:name, :client_id, operands_attributes: [ :id, :operator, :numeric_operand, :formula_id, :_destroy ])
end
# ..
end
模型 "Formula" 有许多 "Operands" 使用 simple_nested_form 创建,使用字段。看来流程是正确的,启动没有错误,但是操作数没有保存。
公式模型:
class Formula < ActiveRecord::Base
attr_accessible :name, :client_id
validates_presence_of :name, :client_id
belongs_to :client
has_many :operands, as: :operation, dependent: :destroy
accepts_nested_attributes_for :operands, allow_destroy: true
attr_accessor :operator, :numeric_operand, :operation_id, :operation_type
end
运算模型:
class Operand < ActiveRecord::Base
attr_accessible :operator, :numeric_operand, :operation_id, :operation_type
validates_presence_of :operator
belongs_to :operation, polymorphic: true
OPERATOR_TYPES = ["+", "-", "*", "/"]
end
公式控制器:
class FormulasController < ApplicationController
load_and_authorize_resource
def new
@formula.operands.build
end
def create
@formula = Formula.new(params[:formula])
@formula.client_id = @current_client.id unless @formula.client_id.present?
if @formula.save
redirect_to @formula, notice: t('controllers.notice.successfully_created') }
else
render action: "new"
end
end
def edit
end
def update
if @formula.update_attributes(params[:formula])
redirect_to @formula, notice: t('controllers.notice.successfully_updated')
else
render action: "edit"
end
end
公式_表格:
= simple_nested_form_for @formula, :html => { :class => 'form-vertical' } do |f|
= f.error_notification
.form-inputs
.row
.span3= f.input :name
.well
= f.fields_for :operands
= f.link_to_add t('helpers.links.add'), :operands
.form-actions
= f.button :submit, :class => 'btn-primary', disable_with: "#{t('helpers.links.submitting')}"
_operands_fields:
.well
.row
.span2= f.input :operator, collection: Operand::OPERATOR_TYPES
.span3= f.input :numeric_operand
这一切似乎工作正常,但是当进程结束时,没有创建操作数。在使用更好的错误检查更新或创建方法中返回的参数时,从表单中成功检索操作数属性,但未创建公式与它们之间的关系:
>> @formula.operands.all
=> #<ActiveRecord::AssociationRelation []>
>> @formula.operands.first
=> nil
>> params
=> {"utf8"=>"✓", "_method"=>"patch", "authenticity_token"=>"--TOKEN--", "formula"=>{"name"=>"Sdfg", "operands_attributes"=>{"1457352032591"=>{"operator"=>"+", "numeric_operand"=>"3"}}}, "commit"=>"Update Formula", "action"=>"update", "controller"=>"formulas", "locale"=>"en", "id"=>"3"}
>>
更新(使用强参数)
继续我们的讨论,即 protected_attributes
不适用于 Rails 4(未验证)中的多态关联的嵌套属性,然后我建议使用强参数:
class FormulasController < ApplicationController
# ..
def formula_params
params.require(:formula).permit(:name, :client_id, operands_attributes: [ :id, :operator, :numeric_operand, :formula_id, :_destroy ])
end
# ..
end