3 votes

Comment DRY un formulaire partiel Rails 6

Cela fonctionne, mais je veux assécher le code de mon formulaire.

/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

J'ai essayé de modifier les vues "edit" et "new" pour passer l'URL.

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

Mais cela provoque une erreur de syntaxe :

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

Dans _form.html.erb, si j'inclus simplement le formulaire en utilisant <%= render 'form' %> avec :

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

L'édition fonctionne, mais la nouvelle donne lieu à cette erreur :

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

Quand j'essaie <%= form_for(@user_job) do |form| %> J'ai compris :

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

pour les nouveaux.

Quand j'essaie <%= form_with model: @user_job, local: true do |form| %> J'ai compris :

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

ce qui semble faux car rails routes montre :

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

etc. J'ai fait des recherches et la plupart des conseils donnés il y a plusieurs années consistent à passer une URL. J'ai lu la documentation Rails sur les formulaires, les partiels et le tutoriel du blog. Je pense que je fais une erreur très simple.

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

3voto

papirtiger Points 1870

Pour créer un formulaire qui se dirige vers une route imbriquée, vous passez un tableau :

# 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 %>

Mais on peut se demander pourquoi vous avez imbriqué la route en premier lieu puisque vous ne l'utilisez pas du tout comme une ressource imbriquée. GET /users/:user_id/jobs ne devrait vraiment montrer que les travaux appartenant à cet utilisateur et POST /users/:user_id/jobs doit créer un travail appartenant à cet utilisateur et non à l'utilisateur actuel.

1voto

rkalra Points 353

Mis à jour : Je n'ai pas remarqué les routes.

Vous pourriez créer un _form.html.erb partiel comme ceci : Pour les routes imbriquées, vous devez passer le user également.

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

et changez votre new.html.erb y edit.html.erb fichiers quelque chose comme :

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

current_user puisque vous utilisez devise

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X