How to merge nested attributes in permit + Rails
Asked Answered
R

5

6
params.require(:task).permit(:summary, comments_attributes: [:id, :content])

I want to add user_id and project_id in comments_attributes.

user_id    = current_user.id
project_id = project.id

I tried with below but not working

params.require(:task).permit(:summary, comments_attributes: [:id, :content]).merge(user_id: current_user.id, comments_attributes: [user_id: current_user.id, project_id: project.id])

Please help me how can I do this?

Redstart answered 5/12, 2016 at 18:47 Comment(0)
Z
2

Although an old question, the right answer IMHO is this ->

In Rails 5, instead of .to_h.deep_merge you should use reverse_merge

params.require(:task).permit(:summary, comments_attributes: [:id, :content]).reverse_merge(user_id: current_user.id, comments_attributes: [user_id: current_user.id, project_id: project.id])
Zales answered 10/9, 2019 at 18:35 Comment(0)
L
1

you will have to use deep_merge

params.require(:task).permit(:summary, comments_attributes: [:id, :content]).deep_merge(user_id: current_user.id, comments_attributes: [user_id: current_user.id, project_id: project.id])
Lavalava answered 5/12, 2016 at 18:59 Comment(3)
How does this work in Rails 5? It seems that deep_merge is no longer a subclass of ActionController::Parameters. I am getting an undefined method error for deep_merge in Rails 5.Silicious
@Silicious check the new answer. All the bestZales
@Silicious try to use reverse_mergePrefigure
C
1

Convert permitted params to hash first, and then deep merge the hash:

params.require(:task).permit(
    :summary,
    comments_attributes: [
        :id,
        :content
    ]
).to_h.deep_merge(
    user_id: current_user.id,
    comments_attributes: [
        user_id: current_user.id,
        project_id: project.id
    ]
)
Cumin answered 20/9, 2018 at 8:1 Comment(0)
B
1

I could not get the current top answer to work. reverse_merge on its own does not appear to iteratively call reverse_merge down to the nested comments_attributes version of ActionController::Parameters. Rather, I needed to do something like this:

_params = params.require(:task).permit(:summary, comments_attributes: [:id, :content])
_params.reverse_merge!(user_id: current_user.id)
_params[:comments_attributes].each do |key, value|
  _params[:comments_attributes][key] = value.reverse_merge(user_id: current_user.id, project_id: project.id)
end
_params

Happy to hear if there is an more straightforward answer!

Bemire answered 22/2, 2023 at 21:11 Comment(0)
P
0
 params[:task][:comments_attributes].merge!({user_id: current_user.id, project_id: project.id})
Particia answered 20/8, 2019 at 13:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.