Rails 嵌套表单的参数
Rails params for nested forms
为了获取要为我的嵌套表单保存的数据,我已经奋斗了好几天。我基本上希望能够存储用户取消项目的原因,以及项目被取消之前的最后阶段。但我似乎无法让动作 cancel
、cancel_save
和 cancel_params
发挥得很好!
控制器
before_action :correct_user, only: [:show, :edit, :update, :destroy, :cancel, :cancel_save]
...
def cancel
@project.build_project_close_reason
end
def cancel_save
@project.build_project_close_reason(cancel_params)
@project.update(project_status_id: 10)
redirect_to root_path, notice: 'Project has been successfully cancelled.'
end
private
def correct_user
@user = current_user
@project = current_user.projects.find_by(id: params[:id])
end
redirect_to user_projects_path, notice: "You are not authorised to view this project" if @project.nil?
end
def cancel_params
params.require(:project).permit(project_close_reason_attributes: [:comment]).merge(project_close_reason_attributes: [project_id: @project.id, last_status_id: @project.project_status_id ])
end
型号
class Project < ApplicationRecord
belongs_to :user
has_one :project_close_reason
accepts_nested_attributes_for :project_close_reason #adding this seemed to make no difference?
end
class ProjectCloseReason < ApplicationRecord
belongs_to :project
end
class User < ApplicationRecord
... # All standard devise stuff
has_many :projects
end
视图中的嵌套表单
<%= form_for([@user, @project], url: {action: "cancel_save"}, method: :post) do |f| %>
<%= fields_for :project_close_reason do |pcr| %>
<div class="field entry_box">
<%= pcr.label "Why are you cancelling this project? (This helps us improve!)" %>
<%= pcr.text_area :comment, class: "form-control entry_field_text" %>
</div>
<% end %>
<div class="actions center space_big">
<%= f.submit "Cancel Project", class: "btn btn-lg btn-warning" %>
</div>
<% end %>
路线
devise_for :users
devise_for :admins
resources :users do
resources :projects do
get "cancel", :on => :member
post "cancel" => 'projects#cancel_save', :on => :member
end
end
这是我在尝试提交表单时遇到的错误:
ActionController::ParameterMissing in ProjectsController#cancel_save
param is missing or the value is empty: project
。它引用了 cancel_params
动作
感谢您的帮助!
更新
这是我调用cancel_save
时的日志
Started POST "/users/2/projects/10/cancel" for ::1 at 2016-09-29 10:03:44 +0200
Processing by ProjectsController#cancel_save as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"h6K+VFyjW/dV189YOePWZm+Pmjey50xAMQIJb+c3dzpEaMv8Ckh3jQGOWfVdlfVH/FxolbB45fXvTO0cdplhkg==", "project_close_reason"=>{"comment"=>"b"}, "commit"=>"Cancel Project", "user_id"=>"2", "id"=>"10"}
User Load (11.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
Project Load (0.7ms) SELECT "projects".* FROM "projects" WHERE "projects"."user_id" = AND "projects"."id" = LIMIT [["user_id", 2], ["id", 10], ["LIMIT", 1]]
ProjectCloseReason Load (0.2ms) SELECT "project_close_reasons".* FROM "project_close_reasons" WHERE "project_close_reasons"."project_id" = LIMIT [["project_id", 10], ["LIMIT", 1]]
Completed 400 Bad Request in 22ms (ActiveRecord: 12.1ms)
ActionController::ParameterMissing (param is missing or the value is empty: project):
错误是说 cancel params
的 params.require(:project)
行中没有名称为 project
的参数。我认为这是因为在 form_for
中你提到了 [@user, @project]
,这意味着 user's project
。所以project params must be inside user's
。调用 cancel_save
时检查日志。必须有类似 {user => {project => { } }
.
的内容
最后我完全不需要项目就让它工作了。这是我修改后的cancel_params
在我的projects_controller
。对于任何其他想做这种附加数据库的人,我强烈建议你跳过嵌套形式的参数,如果你能这样做的话。 简单多了!
private
def cancel_params
params.require(:project_close_reason).permit(:comment).merge(project_id: @project.id, last_status_id: @project.project_status_id )
end
为了获取要为我的嵌套表单保存的数据,我已经奋斗了好几天。我基本上希望能够存储用户取消项目的原因,以及项目被取消之前的最后阶段。但我似乎无法让动作 cancel
、cancel_save
和 cancel_params
发挥得很好!
控制器
before_action :correct_user, only: [:show, :edit, :update, :destroy, :cancel, :cancel_save]
...
def cancel
@project.build_project_close_reason
end
def cancel_save
@project.build_project_close_reason(cancel_params)
@project.update(project_status_id: 10)
redirect_to root_path, notice: 'Project has been successfully cancelled.'
end
private
def correct_user
@user = current_user
@project = current_user.projects.find_by(id: params[:id])
end
redirect_to user_projects_path, notice: "You are not authorised to view this project" if @project.nil?
end
def cancel_params
params.require(:project).permit(project_close_reason_attributes: [:comment]).merge(project_close_reason_attributes: [project_id: @project.id, last_status_id: @project.project_status_id ])
end
型号
class Project < ApplicationRecord
belongs_to :user
has_one :project_close_reason
accepts_nested_attributes_for :project_close_reason #adding this seemed to make no difference?
end
class ProjectCloseReason < ApplicationRecord
belongs_to :project
end
class User < ApplicationRecord
... # All standard devise stuff
has_many :projects
end
视图中的嵌套表单
<%= form_for([@user, @project], url: {action: "cancel_save"}, method: :post) do |f| %>
<%= fields_for :project_close_reason do |pcr| %>
<div class="field entry_box">
<%= pcr.label "Why are you cancelling this project? (This helps us improve!)" %>
<%= pcr.text_area :comment, class: "form-control entry_field_text" %>
</div>
<% end %>
<div class="actions center space_big">
<%= f.submit "Cancel Project", class: "btn btn-lg btn-warning" %>
</div>
<% end %>
路线
devise_for :users
devise_for :admins
resources :users do
resources :projects do
get "cancel", :on => :member
post "cancel" => 'projects#cancel_save', :on => :member
end
end
这是我在尝试提交表单时遇到的错误:
ActionController::ParameterMissing in ProjectsController#cancel_save
param is missing or the value is empty: project
。它引用了 cancel_params
动作
感谢您的帮助!
更新
这是我调用cancel_save
Started POST "/users/2/projects/10/cancel" for ::1 at 2016-09-29 10:03:44 +0200
Processing by ProjectsController#cancel_save as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"h6K+VFyjW/dV189YOePWZm+Pmjey50xAMQIJb+c3dzpEaMv8Ckh3jQGOWfVdlfVH/FxolbB45fXvTO0cdplhkg==", "project_close_reason"=>{"comment"=>"b"}, "commit"=>"Cancel Project", "user_id"=>"2", "id"=>"10"}
User Load (11.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT [["id", 2], ["LIMIT", 1]]
Project Load (0.7ms) SELECT "projects".* FROM "projects" WHERE "projects"."user_id" = AND "projects"."id" = LIMIT [["user_id", 2], ["id", 10], ["LIMIT", 1]]
ProjectCloseReason Load (0.2ms) SELECT "project_close_reasons".* FROM "project_close_reasons" WHERE "project_close_reasons"."project_id" = LIMIT [["project_id", 10], ["LIMIT", 1]]
Completed 400 Bad Request in 22ms (ActiveRecord: 12.1ms)
ActionController::ParameterMissing (param is missing or the value is empty: project):
错误是说 cancel params
的 params.require(:project)
行中没有名称为 project
的参数。我认为这是因为在 form_for
中你提到了 [@user, @project]
,这意味着 user's project
。所以project params must be inside user's
。调用 cancel_save
时检查日志。必须有类似 {user => {project => { } }
.
最后我完全不需要项目就让它工作了。这是我修改后的cancel_params
在我的projects_controller
。对于任何其他想做这种附加数据库的人,我强烈建议你跳过嵌套形式的参数,如果你能这样做的话。 简单多了!
private
def cancel_params
params.require(:project_close_reason).permit(:comment).merge(project_id: @project.id, last_status_id: @project.project_status_id )
end