嵌套资源 w/ Rails 5.1 form_with
Nested Resources w/ Rails 5.1 form_with
根据 this pull request 我可以看到应该将一个数组传递给 form_with
的模型参数。但是,当我提供以下内容时:
<%= form_with(model: [@trip, @activity], local: true) do |f| %>
...
<% end %>
Rails 将 return - ActionView::Template::Error (undefined method activity_path' for #<#<Class:0x007f80231e3070>:0x007f8023010dd8>):
我的路由文件如下所示:
resources :trips do
resources :activities
end
rake routes
的输出看起来像 -
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
还有我的 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 - 我应该如何为嵌套资源设置我的 form_with,为什么这种形式认为我想使用 activity_path
?理想情况下,我想将此表单移动到部分表单中,并为我的#new 和#edit 操作使用相同的表单。
您只需要将 url 添加到您希望表单指向的路径,即:, url: trip_activity_path
或者您要访问的任何路径
尝试分别指定模型和 url:
form_with(model: @activity, url: [@trip, @activity])
根据文档,url
的值是 "Akin to values passed to url_for or link_to",因此使用数组应该可行。
这也适用于浅嵌套,因为数组被压缩了。
添加到,如果你想支持浅嵌套你也可以使用:
form_with(model: [@trip, @activity])
并更改 edit.html.erb 上的渲染以将 nil 传递给 trip,例如:
<%= render 'form', trip: nil, activity: @activity %>
并让它通过您的 new.html.erb
中的行程模型
更改 url 没问题,但您可以改为更改允许构建器推断 url 和任何范围等的模型:
<%= form_with(model: child.new_record? ? [@parent, child] : child, local: true) do |form| %>
new/edit 观看次数:<%= render 'form', child: @child %>
控制器将需要从 url 参数设置 @parent,这是嵌套资源的惯例。
根据 this pull request 我可以看到应该将一个数组传递给 form_with
的模型参数。但是,当我提供以下内容时:
<%= form_with(model: [@trip, @activity], local: true) do |f| %>
...
<% end %>
Rails 将 return - ActionView::Template::Error (undefined method activity_path' for #<#<Class:0x007f80231e3070>:0x007f8023010dd8>):
我的路由文件如下所示:
resources :trips do
resources :activities
end
rake routes
的输出看起来像 -
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
还有我的 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 - 我应该如何为嵌套资源设置我的 form_with,为什么这种形式认为我想使用 activity_path
?理想情况下,我想将此表单移动到部分表单中,并为我的#new 和#edit 操作使用相同的表单。
您只需要将 url 添加到您希望表单指向的路径,即:, url: trip_activity_path
或者您要访问的任何路径
尝试分别指定模型和 url:
form_with(model: @activity, url: [@trip, @activity])
根据文档,url
的值是 "Akin to values passed to url_for or link_to",因此使用数组应该可行。
这也适用于浅嵌套,因为数组被压缩了。
添加到
form_with(model: [@trip, @activity])
并更改 edit.html.erb 上的渲染以将 nil 传递给 trip,例如:
<%= render 'form', trip: nil, activity: @activity %>
并让它通过您的 new.html.erb
中的行程模型更改 url 没问题,但您可以改为更改允许构建器推断 url 和任何范围等的模型:
<%= form_with(model: child.new_record? ? [@parent, child] : child, local: true) do |form| %>
new/edit 观看次数:<%= render 'form', child: @child %>
控制器将需要从 url 参数设置 @parent,这是嵌套资源的惯例。