首页 > 解决方案 > Rails has_man 通过关联删除路径

问题描述

我有一个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)           

我不喜欢这个,但我现在可以接受。

但是每当我尝试删除 a 时,我都会遇到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 %>

但这感觉很hacky,我认为我不需要特定的表单,这导致表单使用我不想要的javascript提交。

标签: ruby-on-rails

解决方案


可能的解决方案是在路由中使用浅嵌套( 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' %>

推荐阅读