【问题标题】:Rails params for nested forms嵌套表单的 Rails 参数
【发布时间】:2016-09-29 08:04:34
【问题描述】:

我已经为获取数据以保存嵌套表单而奋斗了好几天。我基本上希望能够存储用户取消项目的原因,以及项目被取消之前的最后阶段。但我似乎无法让cancelcancel_savecancel_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" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 2], ["LIMIT", 1]]
Project Load (0.7ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."user_id" = $1 AND "projects"."id" = $2 LIMIT $3  [["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" = $1 LIMIT $2  [["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):

【问题讨论】:

    标签: ruby-on-rails parameters nested-forms


    【解决方案1】:

    错误是说没有名称为project 的参数,您试图在cancel paramsparams.require(:project) 行中要求该参数。我认为这是因为form_for 你提到了[@user, @project],这意味着user's project。所以project params must be inside user's。致电cancel_save 时检查您的日志。一定有{user =&gt; {project =&gt; { } }之类的东西。

    【讨论】:

    • 我已经更新了上面的内容,以便在我运行 cancel_save 操作时包含日志。这很奇怪,因为我有看起来非常相似的标准 project_params 操作(包括与其他 RESTful 操作一起使用的 .require(:project)
    • 这些是我为项目运行new 操作时的参数,该操作使用project_params。参数:{"utf8"=>"✓", "authenticity_token"=>"Wg7ZMcOfhFxXyaHcN67phcuG27eKWGt+QpF+p3wnXGSZxKyZlXSoJgOQN3FT2MqkWFUpFYjHwsuc35rU7YlKzA==", "project"=>{"project_type_id"=>"1", "name"=>" - 这只是一个测试名称", "description"=>"这是一个测试描述", "industry_id"=>"1", "feature_ids"=>[""], "addon_ids"=>[""] , "budget_id"=>"1"}, "commit"=>"保存项目", "user_id"=>"2"}
    • 谢谢,我对嵌套方面感到非常沮丧,我只是解决了它。在我摆脱 :project 的地方发布了一个新答案。谢谢!
    【解决方案2】:

    最后,我完全不需要项目就让它工作了。这是我在projects_controller 中修改后的cancel_params。对于其他想要进行这种附加数据库的人,如果您可以这样做,我强烈建议您跳过嵌套形式的参数。 简单多了!

    private
    
    def cancel_params
      params.require(:project_close_reason).permit(:comment).merge(project_id: @project.id, last_status_id: @project.project_status_id )
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多