Reputation: 804
I have a place
model and a user
model and a user_place
model, user_place
belongs to user
and place
both. Traditional has_many through association.
I have a page where you can view the users associated with a place. My routes look like:
resources :places do
resources :user_places
end
which generates these routes:
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)
I don't love this but I'm ok with it for now.
But whenever I try to delete a user_place
I have all sorts of issues.
<%= 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]
I had this working previously with slightly different routes and an actual form:
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 %>
But this feels hacky, I don't think I should need a specific form, and this was leading the form to be submitted with javascript which I don't want.
Upvotes: 0
Views: 131
Reputation: 1507
What might be a solution is to use shallow nesting in the routes (shallow: true).
resources :places do
resources :user_places, shallow: true
end
Make sure to run rails routes
again. The delete method of a user_place will no longer be nested.
You can then simply delete the user_place passing a single variable (an instance of a user place, @user_place). There is no need to set the id (place_id or id) as Rails is smart enough to handle that. Just passing an instance variable is enough for the delete method to find the corresponding record.
<%= link_to "delete", user_place_url(@user_place), method: 'delete' %>
Upvotes: 1