【问题标题】:How to DRY a Rails 6 partial form如何干燥 Rails 6 部分形式
【发布时间】:2020-08-27 06:17:22
【问题描述】:

这可行,但我想干掉我的表单代码。

/app/views/jobs/edit.html.erb:

<h1>Edit Job</h1>
<%= form_with model: @job, url: user_job_path(current_user.id), method: "patch", local: true do |form| %>
    <!-- contents of form -->
<% end %>

/app/views/jobs/new.html.erb:

<h1>Add Job</h1>
<%= form_with scope: :job, url: user_jobs_path(current_user.id), local: true do |form| %>
  <!-- contents of form -->
<% end %>

/app/controllers/jobs_controller.rb:

class JobsController < ApplicationController
  def new
    @job = Job.new
  end

  def edit
    @job = Job.find(params[:id])
  end

  def create
    @job = Job.new(job_params)
    @job.user_id = current_user.id

    if @job.save
      redirect_to user_jobs_path(current_user.id)
    else
      render 'new'
    end
  end

  def update
    @job = Job.find(params[:id])
    @job.user_id = current_user.id

    if @job.update(job_params)
      redirect_to user_jobs_path(current_user.id)
    else
      render 'edit'
    end
  end
  ...
end

/config/routes.rb:

Rails.application.routes.draw do
  resources :users do
    resources :jobs
  end
  ...
end

我尝试更改编辑和新视图以传递 URL。

new.html.erb:

<%= render partial: "form", locals: {job: @job, url: user_jobs_path(current_user.id)} %>

edit.html.erb:

<%= render partial: "form", locals: {job: @job, url: user_jobs_path(current_user.id, job.id)} %>

_form.html.erb:

<%= form_for(job) url: url do |form| %>
  <!-- contents of form -->
<% end %>

但是会导致语法错误:

Encountered a syntax error while rendering template: check <%= form_for(job) url: url do |form| %>  

在 _form.html.erb 中,如果我简单地使用 &lt;%= render 'form' %&gt; 包含表单:

<%= form_with scope: :job, url: user_job_path(current_user.id), method: "patch", local: true do |form| %>
...

编辑有效,但新结果导致此错误:

No route matches {:action=>"show", :controller=>"jobs", :user_id=>1}, missing required keys: [:id]

当我尝试&lt;%= form_for(@user_job) do |form| %&gt; 时,我得到:

"First argument in form cannot contain nil or be empty" 

换新的。

当我尝试&lt;%= form_with model: @user_job, local: true do |form| %&gt; 时,我得到:

No route matches [POST] "/users/1/jobs/new"

这似乎是错误的,因为rails routes 显示:

new_user_job GET    /users/:user_id/jobs/new(.:format)                                                       jobs#new

等等。我搜索了几年前的大部分建议是传递一个 URL。我阅读了 Rails 文档中的表单、部分和博客教程。我怀疑我犯了一个非常简单的错误。

<%= form_with scope: :job, url: user_job_path(current_user.id), method: "patch", local: true do |form| %> 

【问题讨论】:

  • urlform_for 的参数,所以将 form_for(job) url: url 更改为 form_for(job, url: url)
  • @theTinMan 我进行了一些编辑以删除与问题无关的代码。那是你暗示的吗?我应该进行其他更改吗?

标签: ruby-on-rails ruby forms partials


【解决方案1】:

要创建一个路由到嵌套路由的表单,您需要传递一个数组:

# app/views/jobs/_form.html.erb
<%= form_with(model: [user, job]) %>
  # ...
<% end %>
# app/views/jobs/new.html.erb
<%= render 'form' user: current_user, job: @job %>
# app/views/jobs/edit.html.erb
<%= render 'form' user: current_user, job: @job %>

但是,为什么您首先嵌套了路由,因为您根本没有将它用作嵌套资源,这有点令人怀疑。 GET /users/:user_id/jobs 应该只显示属于该用户的作业,POST /users/:user_id/jobs 应该创建属于该用户而不是当前用户的作业。

【讨论】:

  • 哇,三个字母的用户名!谢谢你。我不完全明白你所说的关于嵌套的内容,但你可能正在做一些我应该改变的事情。我猜是因为作业是用户的孩子,我认为它应该是嵌套的。我会尝试改变路线,所以它不是嵌套的。再次感谢!
  • 你说得对,我不需要嵌套。我已经删除它并且它有效。谢谢!!
【解决方案2】:

更新:我没有注意到路线。

您可以像这样创建_form.html.erb 部分: 对于嵌套路由,您还需要传递 user 对象。

<%= form_with(model: [user, job]) do |form| %>
  <!-- contents of your form -->
<% end %>

并更改您的 new.html.erbedit.html.erb 文件,例如:

<%= render 'form', job: @job, user: current_user %>

current_user 因为你使用的是设计

【讨论】:

  • 嗯。 . .我试过这个并得到: Showing ~/git/EmpEmp/app/views/jobs/_form.html.erb where line #1 raise: undefined method `jobs_path' for #:0x00007f49fc912dd0>
  • @max 是正确答案,无论如何我都更新了答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-26
  • 2012-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多