1

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"}
>>
2
  • Seems like you are not using strong params, so I guess you are using Rails 3. Can you try .save! instead of .save? So that errors are raised (in case there are), and not silently fail. Commented Mar 7, 2016 at 12:43
  • I use Rails 4, but the gem 'protected_attributes' lets me handle accessibility in a Rails 3 way. I have tried using .save! but the issue persist. Commented Mar 7, 2016 at 12:50

1 Answer 1

1

Update (Using Strong Params)

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
Sign up to request clarification or add additional context in comments.

10 Comments

Wow, such a lapsus... Ok, I've added this, and now operands are created... But all attributes are set to nil.
Your Operand model has attr_accessible :operand, :numeric_operand, so those attributes should have been sanitized already. I am not sure why you're getting nil. I can only guess that maybe the polymorphic association has something to do with this.
I've tried it with a non polymorphic relationship and it seems to work fine... This is a great inconvenience :(
@PradeMismo, you might want to try strong params for this. Maybe the protected_attributes gem does not support sanitizing polymorphic association. I imagine it has already been deprecated in favor of strong params, which might be the reason of some bugs / incompatibilities. Maybe other user know how to deal with this though. I haven't really used protected_attributes since Rails 3
Any help about strong parameters? tried this def formula_params params.require(:formula).permit(:name, :client_id, operands_attributes: [ :operator, :numeric_operand, :formula_id ]) end thing, but still getting ActiveModel::ForbiddenAttributesError.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.