Rails - Simple Form with Nested Attributes

237 views Asked by At

I am trying to make an app with Rails 4 and Simple Form.

I have three models, being: Project, Scope and Background.

Project has one scope. Scope has one background. Scope belongs to project. Background belongs to scope. Project accepts nested attributes for Scope. Scope accepts nested attributes for background.

Project.rb: has_one :scope accepts_nested_attributes_for :scope

Scope.rb:

belongs_to :project
accepts_nested_attributes_for :background

Background.rb

  belongs_to :scope

The scope params are permitted in the project controller. Also, the background attributes are permitted inside the project controller (as scope attributes).

The background params are also permitted in the background controller.

The permitted params in each controller include the relevant _id.

So in the:

  • background controller, the permitted params include :scope_id (not :background_id)
    • scope controller, the permitted params include :project_id

This is because these are the foreign keys for those models that belong to another model.

Project controller:

def project_params
      params[:project].permit(
      :title, :project_id, scope_attributes: [:background, :project_id, background_attributes: [scope_id, title]])

Scope controller:

 def scope_params
    params[:scope].permit(:background, project_id, background_attributes: [scope_id, :title])

Background controller:

params[:background].permit(:scope_id, :title)

My trouble is understanding why, when I edit a project in a field that is actually an attribute of background, the db records show the creation of a new id and a new scope_id?

For example, when I originally create a new project, the Background table has ID 1 and scope_id 4. When I edit this project and go back to look in the Background table of the psql database, the id has become 2 and the scope_id has become 5.

I was expecting these ids to remain as they were orignally because I have only updated the records (not created new ones).

Am I wrong to expect this? Or, have I put the wrong id fields in my permitted params in my controllers? Or, am I wrong to white-label each nested param for background in each of the project, scope and background controller?

2

There are 2 answers

7
Taryn East On

It sounds like you are not actually editing the nested objects, but creating a new one each time. So yes, you should include the id in the nested part of the form, and also int he X_attributes section of the require/permit settings in the controller

5
Pavan On

Your project_params should look like this

def project_params
   params.require(:project).permit(:id,:title, scope_attributes: [:id,:background, :project_id, background_attributes: [:id,scope_id, title]])
end