Per cette requête d'extraction Je peux voir qu'un tableau doit être passé au paramètre de modèle de form_with
. Cependant, lorsque je fournis ce qui suit:
<%= form_with(model: [@trip, @activity], local: true) do |f| %>
...
<% end %>
Les rails vont revenir - ActionView::Template::Error (undefined method activity_path' for #<#<Class:0x007f80231e3070>:0x007f8023010dd8>):
Mon fichier de routes ressemble à:
resources :trips do
resources :activities
end
La sortie de rake routes
ressemble à -
trip_activities GET /trips/:trip_id/activities(.:format) activities#index
POST /trips/:trip_id/activities(.:format) activities#create
new_trip_activity GET /trips/:trip_id/activities/new(.:format) activities#new
edit_trip_activity GET /trips/:trip_id/activities/:id/edit(.:format) activities#edit
trip_activity GET /trips/:trip_id/activities/:id(.:format) activities#show
PATCH /trips/:trip_id/activities/:id(.:format) activities#update
PUT /trips/:trip_id/activities/:id(.:format) activities#update
DELETE /trips/:trip_id/activities/:id(.:format) activities#destroy
trips GET /trips(.:format) trips#index
POST /trips(.:format) trips#create
new_trip GET /trips/new(.:format) trips#new
edit_trip GET /trips/:id/edit(.:format) trips#edit
trip GET /trips/:id(.:format) trips#show
PATCH /trips/:id(.:format) trips#update
PUT /trips/:id(.:format) trips#update
DELETE /trips/:id(.:format) trips#destroy
Et mon activities_controller.rb -
before_action :set_activity, only: %i[show update edit destroy]
def edit; end
def update
dates = calculate_datetimes(params[:date_range])
@activity.assign_attributes(name: params[:name],
summary: params[:summary],
start_datetime: dates[0],
end_datetime: dates[1])
if @activity.save
flash[:success] = 'Activity successfully updated'
redirect_to(@trip)
else
set_humanized_daterange
render :edit
end
end
private
def set_activity
@activity = Activity.find(params[:id])
end
tl; dr - Comment dois-je configurer mon formulaire avec une ressource imbriquée, et pourquoi ce formulaire pense-t-il que je souhaite utiliser le activity_path
? Idéalement, j'aimerais déplacer ce formulaire dans un partiel et utiliser le même formulaire pour mes actions #new et #edit.
Essayez de spécifier le modèle et l’URL séparément:
form_with(model: @activity, url: [@trip, @activity])
Selon la documentation, les valeurs de url
sont "des valeurs semblables à celles transmises à url_for ou link_to", de sorte que l'utilisation d'un tableau devrait fonctionner.
Pour prendre en charge l’imbrication peu profonde, vous pouvez utiliser une condition comme ceci:
form_with(model: @activity, url: (@activity.new_record? ? [@trip, @activity]: @activity))
Il vous suffit d’ajouter l’URL à l’itinéraire auquel vous souhaitez que le formulaire pointe, par exemple: , url: trip_activity_path
Changer l'URL est acceptable, mais vous pouvez plutôt changer le modèle, ce qui permet au constructeur de déduire l'URL et toute portée, etc.:
<%= form_with(model: child.new_record? ? [@parent, child] : child, local: true) do |form| %>
nouveau/modifier vues: <%= render 'form', child: @child %>
les contrôleurs devront définir @parent à partir des paramètres d'URL, ce qui est de toute façon une convention pour les ressources imbriquées.