如何DRY Rails 6的部分表单?

问题描述 投票:0回答:1

这可以工作,但我想把我的表单代码DRY起来。

appviewsjobsedit.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 %>

appviewsjobsnew.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 %>

appcontrollersjobs_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

configroutes.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中,如果我只是简单地将表单用 <%= render 'form' %> 与。

<%= 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]

当我尝试 <%= form_for(@user_job) do |form| %> 我得到。

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

对于新的。

当我尝试 <%= form_with model: @user_job, local: true do |form| %> 我明白了。

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

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

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

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

<%= form_with scope: :job, url: user_job_path(current_user.id), method: "patch", local: true do |form| %> 
ruby-on-rails ruby forms partials
1个回答
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 应创建属于该用户而非当前用户的作业。


1
投票

更新了。 我没有注意到路径。

你可以创建一个 _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 既然你在使用devise

© www.soinside.com 2019 - 2024. All rights reserved.