0
votes

This is my first try at using models with associations with Rails 4 and for some reason I'm not able to get at the parameters POST'ed in due to a "Unpermitted parameters" error. I have tried to permit the associated fields several different ways with no success.

Basically, I have an Adoption Request with an associated Person.

class AdoptionRequest < ActiveRecord::Base
  has_one :person

  accepts_nested_attributes_for :person
end

and

class Person < ActiveRecord::Base
    belongs_to :adoption_request
end

Here are the relevant sections from adoption_requests_controller.rb:

def create
    @adoption_request = AdoptionRequest.new(adoption_request_params)

    respond_to do |format|
        if @adoption_request.save
            format.html { redirect_to @adoption_request, notice: 'Adoption request was successfully created.' }
            format.json { render action: 'show', status: :created, location: @adoption_request }
        else
            format.html { render action: 'new' }
            format.json { render json: @adoption_request.errors, status: :unprocessable_entity }
        end
    end
end

private
    def adoption_request_params
        params.require(:adoption_request).permit(person_attributes: [:first_name, :last_name])
    end

The form in the view is generated using rails-bootstrap-forms:

= bootstrap_form_for @adoption_request do |f|
    = f.fields_for @adoption_request.person do |owner_fields|
        = owner_fields.text_field :first_name
        = owner_fields.text_field :last_name
    = f.submit

Here is an example of the HTML generated by this for the first name field:

 <input class="form-control" id="adoption_request_person_first_name" name="adoption_request[person][first_name]" type="text">

Now when I submit the following POST payload:

{"utf8"=>"✓", "authenticity_token"=>"kE1Q222VzXRsuLnhiO0X3mijW1TGTWSAOVgVDz/rxsE=", "adoption_request"=>{"person"=>{"first_name"=>"John", "last_name"=>"Smith"}}, "commit"=>"Create Adoption request"}

The adoption request is created, but the associated person is not. This is appears to be happening because strong parameters is not allowing the person parameters to come through. Case in point, I see this in the rails console output:

Unpermitted parameters: person

According to the strong parameters documentation, this configuration should work, but I have also tried:

params.require(:adoption_request).permit(:person, person_attributes: [:first_name, :last_name])

which results in the same error ("Unpermitted parameters: person"), and

params.require(:adoption_request).permit!

works to allow the parameters through, but this is not an acceptable solution as it negates the whole purpose of using strong parameters.

What am I doing wrong?

Here is my Gemfile, in case it is helpful:

source 'https://rubygems.org'

ruby '2.0.0'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.0.3'

# Use postgresql as the database for Active Record
gem 'pg'

# Use SCSS for stylesheets
gem 'sass-rails', '~> 4.0.0'

# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'

# Use jquery as the JavaScript library
gem 'jquery-rails'

# Turbolinks makes following links in your web application faster. Read more:     https://github.com/rails/turbolinks
gem 'turbolinks'

# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 1.2'

group :doc do
    # bundle exec rake doc:rails generates the API under doc/api.
    gem 'sdoc', require: false
end

# Use Bootstrap
gem 'bootstrap-sass', '~> 3.3.4'

# Use Figaro to make using environment variables easier
gem 'figaro'

# Use Slim templating engine
gem "slim-rails"

# User authlogic for authentication system
gem 'authlogic'

# Use rails-bootstrap-forms to integrate rails form builder with bootstrap
gem 'bootstrap_form'

group :test do
    # use MiniTest::Spec::DSL
    gem 'minitest-spec-rails', '~> 4.7'
end

The app itself is more complex than this. I've simplified it to illustrate the problem.

Thanks in advance for your help!

2
Your are sending the param "person" inside the "adoption_request" hash, but I believe it should be named "person_attributes". Appears you may need to change how this field is named in your view so that it comes through as desired. Does this help?dave_slash_null
@DRSE That would make sense. But I'm used the standard Rails form helper (well the bootstrap one, which produces practically the same HTML) which I would expect to "just work" end to end since I am using standard Rails conventions. I've updated my question with details on how the view/form is generated.lps
Try changing = f.fields_for @adoption_request.person do |owner_fields| to = f.fields_for person do |owner_fields|Pavan
@Pavan, yes that was the problem. I actually just figured it out as well. I used the following code in the view to generate the correct input names in the the HTML form so that they work automatically with strong parameters as it is documented: = f.fields_for :person do |owner_fields|. Note the model name needs to be a symbol. Using your example results in a syntax error. You did pinpoint the problem though. If you put your comment in as an answer with the correct code I will accept it as the solution. Thanks!lps
That was a typo. I posted it as answer :)Pavan

2 Answers

1
votes

You need to change this line

= f.fields_for @adoption_request.person do |owner_fields| 

to

= f.fields_for :person do |owner_fields|
0
votes

I would simply try building the Person object on save. Pass the first and last names up as hidden fields.

Otherwise I would give strong parameters a read.

if @adoption_request.save
@adoption_request.persons.build(first_name: @first_name, last_name: @last_name)