0

I can't find something that'll lead in the right direction. Everyone else's similar issues with nested resources seems to resolve around accepts_nested_attributes_for… which I'm not trying to do. I'm not trying to save children from the parent, I'm trying to save directly from the child.

In my routes.rb, I have nested my resource

resources :parents, param: :parent do
  resources :children, param: :child
end

parent and child tables both have their own id column, but also have unique index on columns parent and child respectively, which I was to be used in the URL instead of the id.

http://example.com/parents/parent/children/child

This is working fine browsing around going to the show, edit and index actions of each controller.

The problem is there are exceptions saving data.

I'm hoping the root-cause of the issue doesn't come down to a field in the child table is also called child as that's what I've used to override to_param in the model and need to keep it that way.

Navigating to the edit screen: http://example.com/parents/harry/children/sally/edit and pushing submit on the form, returns this NoMethodError exception:

NoMethodError at /parents/harry/children/sally
undefined method `permit' for "sally":String

I'm sure the problem is something to do with how my Strong Parameters line is in children_controller.rb. Can I add to require a hash of :parent and :child maybe?

def children_params
  params.require(:child).permit(:child, :date_of_birth, :nickname)
end

Update 1 (Added params): Here are the request parameters:

{
  "utf8"=>"✓", 
  "_method"=>"patch", 
  "authenticity_token"=>"fAkBvy1pboi8TvwYh8sPDJ6n2wynbHexm/MidHruYos7AqwlKO/09kvBGyWAwbe+sy7+PFAIqKwPouIaE34usg==", 
  "child"=>"sally", 
  "commit"=>"Update Child", 
  "controller"=>"children", 
  "action"=>"update", 
  "parent_parent"=>"harry"
}

Other instance variable in-scope at time of error:

@parent

<Parent id: 1, parent: "harry", description: "", user_id: 1, created_at: "2015-06-27 12:00:15", updated_at: "2015-06-27 12:00:15">

@child

<Child id: 1, child: "sally", date_of_birth: nil, parent_id: 1, nickname: nil, created_at: "2015-06-27 12:00:15", updated_at: "2015-06-27 12:00:15">
Turgs
  • 1,729
  • 1
  • 20
  • 49

2 Answers2

1

From the params, you need to change the children_params like below

def children_params
  params.permit(:child, :date_of_birth, :nickname) 
end
Pavan
  • 33,316
  • 7
  • 50
  • 76
  • Sorry - I've briefly removed this as the answer as it's only part way there. Changing to this makes my tests (using minitest) work, but makes validations fail when users actually *use* the site. – Turgs Jun 28 '15 at 08:11
  • @Turgs Please explain it in your post. – Pavan Jun 28 '15 at 08:26
0

Turns out, the problem did seem to be because the a model attribute is named the same at the model, which is what the params hash is also called (where the real problem seemed to lie).

All I needed to do was rename the params hash.

In children_controller.rb, I had to change:

def children_params
  params.require(:child).permit(:child, :date_of_birth, :nickname)
end

to…

def children_params
  params.require(:anything_else).permit(:child, :date_of_birth, :nickname)
end

and then also change theform_for my form in the new/edit views from:

<%= simple_form_for([@parent, @child]) do |f| %>

to…

<%= simple_form_for([@parent, @child], as: :child_params) do |f| %>

Now, all works well across the board, in both tests and when a user uses the site via the UI as normal.

Turgs
  • 1,729
  • 1
  • 20
  • 49