RESTful add / remove way has multiple associations
I have the following models
class User < ActiveRecord::Base
has_many :user_wishes
has_many :wishes, through: :user_wishes
end
class UserWish < ActiveRecord::Base
belongs_to :user
belongs_to :wish
end
class Wish < ActiveRecord::Base
has_many :user_wishes
has_many :users, through: :user_wishes
end
I now have the following interface where the user can select / deselect.
Once the user is done with a selection / deselection, they will submit the form. Now all I do in the backend is creating or destroying records user_wishes
for data user_id
and wish_id
.
There are now two ways to implement this solution that I could think of.
1. Calculating the difference between existing and new wishes
Say the user already has N wishes , now he makes a new request with M wishes . I will remove the difference (N - M) and add the difference (M - N) . This approach seems very ineffective as I always have to send (N ∩ M) over the network.
End point: /user_wishes
TYPE POST
:? but it also removes the Param entries
: {wish_id: [1,2 ..], user_id: 10}
2. Sending only modified
I will have logic in the frontend that gives me a list of recently added / removed wishes.
End point: /user_wishes
TYPE POST
:? but it also removes the Param entries
: {added_wish_ids: [1,2 ..], removed_wish_ids: [12, 16], user_id: 10}
I'm using this approach right now, but it doesn't seem RESTful to me!
I would like to know the best way to do this. Which endpoint should go and what type of request should be?
source to share
Probably the quietest method of adding / removing these wishes would be to have a nested api structure with separate calls to POST
and DELETE
.
POST /user/:user_id/wish/:wish_id
DELETE /user/:user_id/wish/:wish_id
As the user checks / deselects an item from the list, it sends a POST / DELETE accordingly.
class UserWishController < ApplicationController
def create
user_id = params[:user_id]
wish_id = params[:wish_id]
UserWish.create(user_id: user_id, wish_id: wish_id)
end
def destroy
user_id = params[:user_id]
wish_id = params[:wish_id]
uw = UserWish.find(user_id: user_id, wish_id: wish_id)
uw.destroy if uw.present?
end
end
source to share