The model "Formula" has many "Operands" created using a simple_nested_form, using fields for. It seems the process is correct, and no errors launched, but operands are not saved.
Formula model:
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
Operand model:
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
Formulas controller:
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
Formula _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
This all seem to work fine, but when the proccess ends, no operands are created. When inspecting returned params in update or create methods using better errors, operands attributes are retrieved successfully from the form, but the relationship between formula and them is not created:
>> @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"}
>>
Continuing from our discussion that protected_attributes
doesn't work with nested attributes for a polymorphic association in Rails 4 (unverified), I then suggested to use strong params:
class FormulasController < ApplicationController
# ..
def formula_params
params.require(:formula).permit(:name, :client_id, operands_attributes: [ :id, :operator, :numeric_operand, :formula_id, :_destroy ])
end
# ..
end