嵌套资源w/Rails 5.1 form_with

col*_*ncr 20 ruby-on-rails ruby-on-rails-5.1

根据这个拉取请求,我可以看到一个数组应该被传递给form_with模型参数.但是,当我提供以下内容时:

<%= form_with(model: [@trip, @activity], local: true) do |f| %>
  ...
<% end %>
Run Code Online (Sandbox Code Playgroud)

Rails将返回 - ActionView::Template::Error (undefined method activity_path' for #<#<Class:0x007f80231e3070>:0x007f8023010dd8>):

我的路线文件如下:

  resources :trips do
    resources :activities
  end
Run Code Online (Sandbox Code Playgroud)

输出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
Run Code Online (Sandbox Code Playgroud)

还有我的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
Run Code Online (Sandbox Code Playgroud)

tl; dr - 我应该如何为嵌套资源设置form_with,为什么这个表单认为我想使用activity_path?理想情况下,我想将此表单移动到一个部分,并对我的#new和#edit操作使用相同的表单.

max*_*max 29

尝试分别指定模型和网址:

form_with(model: @activity, url: [@trip, @activity])
Run Code Online (Sandbox Code Playgroud)

根据文档,值为url"类似于传递给url_for或link_to的值",因此使用数组应该有效.

要支持浅嵌套,您可以使用条件,如下所示:

form_with(model: @activity, url: [@trip, @activity])
Run Code Online (Sandbox Code Playgroud)


jfa*_*n23 6

您只需要将 url 添加到您希望表单指向的路线,即:, url: trip_activity_path或您点击的任何路径


Gor*_*ndo 5

添加到max answer,如果您想支持浅嵌套,您还可以使用:

form_with(model: [@trip, @activity])

并更改您的 edit.html.erb 上的渲染以将 nil 传递给 trip,例如:

<%= render 'form', trip: nil, activity: @activity %>

并让它通过你的 new.html.erb 中的旅行模型