2

I am trying to create a form that updates 2 tables - commission_type and commission_tier.

I created the models, controller and form but when I submit it, my commission_tier table does not update. Only my commission_type table updates.

Can someone take a look at my code and tell me what I am doing wrong? I have combed through my code trying to find the mistake, and I cannot find it.

My models

class CommissionType < ApplicationRecord
  has_many :commission_tiers
  accepts_nested_attributes_for :commission_tiers
end
class CommissionTier < ApplicationRecord
  belongs_to :commission_types, optional: true
end

My controller

class Admin::CommissionTypesController < Admin::BaseController


  def index
    @commission_types = CommissionType.all
  end

  def new
    @commission_type = CommissionType.new
    @commission_type.commission_tiers.build
  end

def create
    @commission_type = CommissionType.new(commission_type_params)
    if @commission_type.save
      redirect_to admin_commission_types_index_path
    else
      render "new"
    end
  private

  def commission_type_params
    params.require(:commission_type).permit(:name, :active, :allow_mass_update, :plan,
                                               commission_tiers_attributes: [:id, :increment_value, :rate, :commission_type_id])
  end
end

My form

<%= simple_form_for @commission_type, url: admin_commission_types_index_path, wrapper: :bootstrap2, :html => { :class => 'form-horizontal' } do |f| %>
      <fieldset>
        <legend>Properties</legend>
        <%= f.input :name, label: 'Commission Name' %>

        <%= f.input :active, as: :boolean, label: 'Active?', label_html: { class: 'padding-top' } %>
        <%= f.input :allow_mass_update, as: :boolean,  label: 'Allow mass update?', label_html: { class: 'padding-top' } %>
        <%= f.input :plan, input_html: {id: 'dropdown'},
                    label: 'Commission Type', 
                    collection: [ ['Select One..', 'select'], ['Flat', 'flat'], ['Flat +', 'flat_plus' ], ['Promotional', 'promotional'], ['Straight', 'straight'], ['Waterfall', 'waterfall'],  ['Sliding Scale', 'sliding_scale'] ],
                    selected: 'select'
                    %>
      </fieldset>
     
        
      <fieldset id="flat">
        <legend>Flat Commission</legend>
        <%= f.simple_fields_for :commission_tiers do |builder| %>
          <%= builder.input :rate %>
          <%= builder.input :increment_value %>
        <% end %>
      </fieldset>

My form is displaying and working html form

UPDATE

Some additional details

CommissionType column values = [:name, :active, :allow_mass_update, :plan]

CommissionTier column values = [:id, :increment_value, :rate, :commission_type_id]

Also, when I submit my form, here is an example of what my params are

<ActionController::Parameters {"name"=>"asdf", "active"=>"1", "allow_mass_update"=>"1", "plan"=>"flat", "commission_tiers_attributes"=><ActionController::Parameters {"0"=><ActionController::Parameters {"rate"=>"45"} permitted: true>} permitted: true>} permitted: true>
David Lee
  • 571
  • 6
  • 20
  • Few debugging questions. In place you already have `binding.pry`, what are the values of 1) params 2) commission_type_v2_params 3) @comission_type.comission_tiers. – BroiSatse Apr 05 '21 at 17:52
  • @BroiSatse - I cleaned up my post. Much of that was typos that were part of a debugging process I was trying. CommissionType param values are ` [:name, :active, :allow_mass_update, :plan]` and CommissionTier param values are ` [:id, :increment_value, :rate, :commission_type_id]` Any suggestions are appreciated – David Lee Apr 05 '21 at 19:04
  • 1
    Well for starters you're not even checking if `@commission_type.save` returns true. What do you think will happen if the user where to input invalid data? Also `CommissionTier.attribute_names.map(&:to_sym)` is a mass assignment vulnerability waiting to happen. Explicitly list the attributes the users are supposed to be able to assign even if it means a little bit more typing. – max Apr 05 '21 at 20:18
  • @DavidLee - Right, so these are not really the params, but rather it looks like expected keys. Can you please confirm these are actually present? Can you confirm that all these keys are present after going through strong_params? Also, could you confirm (or post) rendered html of your form? – BroiSatse Apr 05 '21 at 21:58
  • @max - I updated my post to explicitly list the attributes, but it didn't solve the issue. However, I updated my post to reflect the changes you suggested – David Lee Apr 06 '21 at 13:43
  • One thing I forgot to mention was that I'm using the simple form gem. So I needed to use `f.simple_fields_for` Once I added the `f.`, I have params! But my commission_tier table still doesn't update – David Lee Apr 06 '21 at 17:10
  • 2
    Don't you have a typo in CommissionTier? `belongs_to :commission_types` should be `belongs_to :commission_type` in singular form. And I would use `has_many :commission_tiers, inverse_of: :commission_type` in CommissionType - that way commission_type will be automatically set for the nested models and you don't need `optional: false` anymore. – Sergey Burtsev Apr 16 '21 at 13:57
  • are the params you sent the raw params? or the params from the `commission_type_params` method? if not can you add a list of all the unpermitted params ? – Mshka Apr 20 '21 at 09:18
  • Have you already fixed the typo in the *belongs_to* definition like @SergeyBurtsev pointed out? Did that solve your issue? Setting the inverse is not necessary . If you don't use the `:foreign_key`, `:through` or custom scope the inverse should be set automatically. – 3limin4t0r Apr 20 '21 at 12:12
  • Does `@commission_type.commission_tiers` have values? What about `@commission_type.commission_tiers.map { |ct| ct.valid?; ct.errors }`? – Clemens Kofler Apr 21 '21 at 08:03
  • @SergeyBurtsev - That was my issue. Thanks for this. Can you make this an answer, so I can mark it as the correct one? – David Lee Apr 21 '21 at 17:27

0 Answers0