Contexte
Dans mon application, un série est composé de nombreux livres . Une série Afficher permet à un utilisateur de voir tous les livres d'une série et d'ajouter un nouveau livre à la série à l'aide d'un formulaire.
Tous les livres figurant sur la liste de l Afficher contient un lien vers une page Editer pour ce livre. La page d'édition contient la même forme utilisé pour ajouter initialement un livre. Lors de l'édition d'un livre, le formulaire doit se remplir automatiquement avec les informations existantes du livre.
Question
Comment configurer mon form_with
afin qu'il puisse à la fois créer un nouveau livre et modifier un livre existant (en remplissant automatiquement le formulaire de modification) ? J'ai essayé les configurations suivantes, mais elles cassent soit la page Editer, soit la page Afficher :
<%= form_with(model: [ @series, @series.books.build ], local: true) do |form| %>
- Rupture de livre Editer la page
- Erreur : Pas d'erreur, mais le formulaire ne remplit pas automatiquement les données.
<%= form_with(model: @book, url: series_book_path, local: true) do |form| %>
- Ruptures de série Afficher la page
- Erreur :
No route matches {:action=>"show", :controller=>"books", :id=>"6"}, missing required keys: [series_id]
<%= form_with(model: [:series, @book], local: true) do |form| %>
- Ruptures de série Afficher la page
- Erreur :
Undefined method 'model_name' for nil:NilClass
<%= form_with(model: [@series, @series.books.find(@book.id)], local: true) do |form| %>
- Ruptures de série Afficher la page
- Erreur :
undefined method 'id' for nil:NilClass
<%= form_with(model: @book, url: [@series, @book], local: true) do |form| %>
- Coupures lors de la soumission d'un nouveau livre sur la page Show de la série
- Erreur :
No route matches [POST] "/series/6"
Ressources que j'ai consultées :
- https://api.rubyonrails.org/v5.2.2/classes/ActionView/Helpers/FormHelper.html#method-i-form_with
- https://guides.rubyonrails.org/form_helpers.html
- https://guides.rubyonrails.org/routing.html#resource-routing-the-rails-default
- https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/form_helper.rb
Code existant
Vous trouverez ci-dessous des sections dépouillées du code concerné, ainsi que des liens vers l'endroit où elles se trouvent dans mon dépôt GitHub actuel.
resources :series do
resources :books
end
class Book < ApplicationRecord
belongs_to :series
end
class Series < ApplicationRecord
has_many :books, dependent: :destroy
end
create_table "books", force: :cascade do |t|
t.integer "series_number"
t.integer "year_published"
t.integer "series_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["series_id"], name: "index_books_on_series_id"
end
create_table "series", force: :cascade do |t|
t.string "title"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
app/views/series/ show.html.erb
<%= render @series.books %>
<%= render 'books/form' %>
app/views/books/ livre.html.erb
<%= link_to 'Edit', edit_series_book_path(book.series, book) %>
app/views/books/ edit.html.erb
<%= render 'form' %>
app/views/books/ formulaire.html.erb
<%= form_with(model: @book, url: [@series, @book], local: true) do |form| %>
<%= form.label :series_number %>
<%= form.number_field :series_number %>
<%= form.label :year_published %>
<%= form.number_field :year_published %>
<% end %>
app/controllers/ books_controller.rb
class BooksController < ApplicationController
def index
@books = Book.all
end
def show
@book = Book.find(params[:id])
end
def new
@book = Book.new
end
def edit
@series = Series.find(params[:series_id])
@book = @series.books.find(params[:id])
end
def create
@series = Series.find(params[:series_id])
@book = @series.books.create(book_params)
redirect_to series_path(@series)
end
def destroy
@series = Series.find(params[:series_id])
@book = @series.books.find(params[:id])
@book.destroy
redirect_to series_path(@series)
end
private
def book_params
params.require(:book).permit(:year_published, :series_number)
end
end
Itinéraires
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
series_books GET /series/:series_id/books(.:format) books#index
POST /series/:series_id/books(.:format) books#create
new_series_book GET /series/:series_id/books/new(.:format) books#new
edit_series_book GET /series/:series_id/books/:id/edit(.:format) books#edit
series_book GET /series/:series_id/books/:id(.:format) books#show
PATCH /series/:series_id/books/:id(.:format) books#update
PUT /series/:series_id/books/:id(.:format) books#update
DELETE /series/:series_id/books/:id(.:format) books#destroy
series_index GET /series(.:format) series#index
POST /series(.:format) series#create
new_series GET /series/new(.:format) series#new
edit_series GET /series/:id/edit(.:format) series#edit
series GET /series/:id(.:format) series#show
PATCH /series/:id(.:format) series#update
PUT /series/:id(.:format) series#update
DELETE /series/:id(.:format) series#destroy