【问题标题】:Rails fields_for and not creating relationship with nested objectRails fields_for 并且不与嵌套对象创建关系
【发布时间】:2016-03-07 12:31:52
【问题描述】:

模型“公式”有许多使用 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

公式_form:

= 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"}
>>

【问题讨论】:

  • 好像你没有使用强参数,所以我猜你使用的是 Rails 3。你可以试试.save! 而不是.save 吗?这样就会引发错误(如果有),而不是默默地失败。
  • 我使用 Rails 4,但 gem 'protected_attributes' 让我能够以 Rails 3 的方式处理可访问性。我试过使用.save!但问题仍然存在。

标签: ruby-on-rails ruby-on-rails-4 nested-forms fields-for nested-form-for


【解决方案1】:

更新(使用强参数)

继续我们的讨论,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

【讨论】:

  • 哇,这样的失误......好吧,我已经添加了这个,现在操作数被创建......但是所有属性都设置为nil。
  • 您的Operand 模型有attr_accessible :operand, :numeric_operand,所以这些属性应该已经被清理过了。我不知道你为什么得到零。我只能猜测,也许多态关联与此有关。
  • 我已经尝试过使用非多态关系,它似乎工作正常......这是一个很大的不便:(
  • @PradeMismo,您可能想为此尝试强大的参数。也许protected_attributes gem 不支持清理多态关联。我想它已经被弃用以支持强参数,这可能是一些错误/不兼容的原因。也许其他用户知道如何处理这个问题。自 Rails 3 以来,我还没有真正使用过protected_attributes
  • 对强参数有什么帮助吗?尝试了这个def formula_params params.require(:formula).permit(:name, :client_id, operands_attributes: [ :operator, :numeric_operand, :formula_id ]) end 的东西,但仍然得到 ActiveModel::ForbiddenAttributesError。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多