Rails has_many通过关联删除路径



我有一个place模型和一个user模型和一个user_place模型,user_place属于userplace。传统的has_many通过关联。

我有一个页面,您可以查看与某个地方相关的用户。我的路由如下:

  resources :places do
    resources :user_places
  end

生成这些路由:

place_user_places GET    /places/:place_id/user_places(.:format)                                                  user_places#index
                                      POST   /places/:place_id/user_places(.:format)                                                  user_places#create
                 new_place_user_place GET    /places/:place_id/user_places/new(.:format)                                              user_places#new
                edit_place_user_place GET    /places/:place_id/user_places/:id/edit(.:format)                                         user_places#edit
                     place_user_place GET    /places/:place_id/user_places/:id(.:format)                                              user_places#show
                                      PATCH  /places/:place_id/user_places/:id(.:format)                                              user_places#update
                                      PUT    /places/:place_id/user_places/:id(.:format)                                              user_places#update
                                      DELETE /places/:place_id/user_places/:id(.:format)           

我不喜欢这样,但我现在还可以。

但是每当我试图删除user_place时,我就会遇到各种各样的问题。

<%= link_to "delete", place_user_place_url(place_id: @user_place.place_id, id: @user_place.id), method: 'delete' %>
No route matches {:action=>"show", :controller=>"user_places", :id=>nil, :place_id=>2}, possible unmatched constraints: [:id]

我以前用稍微不同的路由和一个实际的形式来工作:

  resources :places do
    resources :user_places, as: 'user', only: %i[index create new]
    delete 'remove_user', to: 'user_places#remove_user'
  end
            <% if user != current_user %>
              <%= form_with model: @user_place, url: place_remove_user_path(@place.id), method: 'delete' do |form| %>
                <%= form.hidden_field :user_id, value: user.id %>
                <%= form.hidden_field :place_id, value: @place.id %>
                <%= form.submit  "delete" %>
              <% end %>
            <% end %>

但这感觉很粗糙,我不认为我应该需要一个特定的表单,这导致表单与javascript一起提交,这是我不想要的。

解决方案是在路由中使用浅嵌套(shallow: true)) .

resources :places do
 resources :user_places, shallow: true
end

确保再次运行rails routes。user_place的delete方法将不再嵌套。

然后,您可以简单地删除user_place,并传递一个变量(用户位置的实例@user_place)。不需要设置id (place_id或id),因为Rails足够智能来处理这个问题。只需传递一个实例变量就足以让delete方法找到相应的记录。
<%= link_to "delete", user_place_url(@user_place), method: 'delete' %>

最新更新