3
votes

I'm trying to embed property groups on my main Person model to help keep my code organised but Rails 4's Strong Params is getting in the way.

The Scenario

I have a Person model and a PersonName model like so:

class Person
  include Mongoid::Document
  embeds_one :name, class_name: 'PersonName'
  accepts_nested_attributes_for :name
end

class PersonName
  include Mongoid::Document
  embedded_in :person, inverse_of: :name
  # fields here
end

I then use the fields_for helper in my form to nest the PersonName attributes in the Person _form:

<%= f.fields_for :name, PersonName.new do |builder| %>
  <!-- etc -->

and finally I permit the name attributes in the controller so that Strong Params allows the nested attributes through:

def person_params
  params.require(:person).permit(:name)
end

The Problem

It doesn't work and I get the error Unpermitted parameters: name_attributes. What's happening is when I call f.fields_for :name ... a "_attributes" get's appended to the fields in the HTML form. e.g. If I have a field first_name then the form looks like this:

<input name="person[name_attributes][first_name] ...>

instead of:

<input name="person[name][first_name] ...>

As far as I can tell this is intended behavior, so it seems like the .permit method is where things are failing to work.

Attempted Work Arounds

I've tried changing the Strong Params line to:

params.require(:person).permit(:name_attributes)

but this doesn't work. Using permit! does work, but I don't like it since as far as I can tell it's a complete anti-pattern.

I've also tried changing :name everywhere to :name_attributes, except in the f.fields_for helper, since the HTML form now had a property that actually existed on my model. Unfortunately this resulted in f.fields_for :name yielding an error saying :name is not a valid proterty.

1

1 Answers

3
votes

Pierre-Louis Gottfrois, was right, this question fixes my problem. Specifically I needed to add:

params.require(:person).permit(name_attributes: [:first_name, ...])

with the key thing being name_attributes followed by a list of the symbols that I wanted to permit.