1

I'm new to rails and have spent way too many hours on this. Thanks a lot, in advance, for any help!

I can't seem to get fields_for and/or accepts_nested_attributes_for to work for my nested attributes. I have a smash_client that has_many contracts and a form that tries to create a smash_client with a parameter and at the same time it tries to also set a parameter on the contract object. The contract belongs_to the smash_client. I've tried a lot of different solutions and have read the docs but I'm still missing something. I get this in my params hash, in the smash_clients_controller.rb

..., "smash_client"=>{"name"=>"fasdf", "user"=>"adam"}, "smash_client_id"=>{"instance_type"=>"spot"},...

from

= form_for @smash_client do |f|
  .field
    = f.label :name
    = f.text_field :name
  .field
    = fields_for :smash_client_id do |c|
      %p
        = c.radio_button :instance_type, 'spot'
        = c.label :instance_type, 'spot'
        = c.radio_button :instance_type, 'on_demand'
        = c.label :instance_type, 'on demand'

  .actions
    = f.submit 'Save'

and

class SmashClient < ActiveRecord::Base
  has_many :contracts, dependent: :destroy
  accepts_nested_attributes_for :contracts, allow_destroy: true, 
    reject_if: proc { |attributes| attributes[:instance_type].blank? }
...  
  def new
    @smash_client = SmashClient.new
    3.times { @smash_client.contracts.build }
  end
...
  def smash_client_params
    @smash_client_params = params.require(:smash_client).
      permit( :user, :name, contracts_attributes: [:instance_type] )
  end
end

and

class Contract < ActiveRecord::Base
  belongs_to :smash_client
  after_create :determine_instance_type_and_start
  before_destroy :stop_instances
...
end

I think the nested params would work if I hard coded it because if I try something like this, in the console, I don't get errors and I get a new SmashClient and Contract.

smash_client_params = {name: 'something', user: 'blah', contracts_attributes: [{instance_type: 'spot'}]}
SmashClient.create( smash_client_params )

I tried using :contracts, @smash_client.contracts and a few other things in the fields_for section. Also tried using select and collection_select but I can't seem to nail down the form. sorry for the long post. Hopefully I got all the useful info with nothing extra in the question. I'd really appreciate some direction or answers. Thanks in advance.

Adam
  • 344
  • 1
  • 15

2 Answers2

1

I finally found it. The :instance_type had to be whitelisted in the Contract model. Thanks again, kalyani. I appreciate the help. Here's the changes to the code above:

.field
  = fields_for :contracts do |c|
    = c.label :instance_type, 'spot instance'
    = c.radio_button :instance_type, 'spot', checked: true
    = c.label :instance_type, 'on demand instance'
    = c.radio_button :instance_type, 'on_demand'

and

def contract_params
  params.require(:contract).
    permit(:id, :name, :instance_id, :smash_client_id, :instance_type)
end
Adam
  • 344
  • 1
  • 15
0

Instead of : fields_for :smash_client_id do |c|

write it as: fields_for :contracts do |c|

Refer: 1. http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for

  1. http://railscasts.com/episodes/196-nested-model-form-part-1

  2. Rails 4 Nested Attributes Unpermitted Parameters ---- refer this for writing the code in controller and view the correct way

Community
  • 1
  • 1
Kalyani
  • 21
  • 5
  • Could you point me to the section in the links I should read? I tried that answer before I posted my question, to no avail. Also, I've tried using :contracts in the fields_for section but that doesn't do the nested params. It also doesn't show up as `:contracts_attributes` in the params hash, it comes in as `:contracts`. I've read through the docs pretty thoroughly but I'm very new to rails so I'm thinking I am missing something still. thanks, by the way! – Adam Apr 14 '15 at 14:54
  • I thought maybe this could help clarify the problem a bit. This is my attempt to create one from the console. `smash_client_params` `=> {:name=>"foo", :user=>"adam", :contracts_attributes=>[{:instance_type=>"spot"}]}` `SmashClient.create smash_client_params` `=> INSERT INTO `smash_clients` (`name`, `user`, `created_at`, `updated_at`) VALUES ('foo', 'adam', 'created at/updated at times' ) INSERT INTO `contracts` (`instance_type`, `smash_client_id`, `created_at`, `updated_at`) VALUES ('spot', 5, 'created at/updated at times')` `=> ROLLBACK SystemStackError: stack level too deep` – Adam Apr 14 '15 at 16:09