Are there RESTful verbs for association actions?

I’m familiar with CRUD and the mapping of the four actions (create, read, update, delete) to the four SQL statements (insert, select, update, destroy).

I have other actions dealing with associations. For example, I want to remove a book from a list. In this case I’m not deleting (destroying) the book record but removing its association from a list. The controller method’s code would look like…

def remove

@list = List.find(params[:id])

@list.books.delete(Book.find(params[:book]))

redirect_to :action => ‘edit’, :id => @list

end

Although the association method is delete. I don’t the user thinking they are deleting the book, and want to convey to them instead that they are removing the book from the list.

I can think of these association related actions:

Remove - remove a record from a list.

Add - to add a record to a list.

Is there a consensus on action names for association related manipulations?

Jose

Jose Hales-Garcia

UCLA Department of Statistics

jose@stat.ucla.edu

Jose Hales-Garcia wrote:

I have other actions dealing with associations. For example, I want to remove a book from a list.

In this specific case you need to read up on has_many :through. It solves this problem nicely by having the relationship represented as a real model instead of an anonymously. So in this case you may have another model called "ListMembership". When you add a book to the list you create on the ListMembership model. When you delete a book from the list you delete on the ListMembership model. This allow you to move back to all your actions being CRUD.

But on the more general level not all actions can be reduced to CRUD by simply introducing more models. Sometimes you really need different actions. In these cases you just need to realized that you need to break out of CRUD (it is just a design pattern and doesn't have to be religiously followed) and move to having actions that are not CRUDdy.

Eric

Hi --

I'm familiar with CRUD and the mapping of the four actions (create, read, update, delete) to the four SQL statements (insert, select, update, destroy).

I have other actions dealing with associations. For example, I want to remove a book from a list. In this case I'm not deleting (destroying) the book record but removing its association from a list. The controller method's code would look like...

def remove
    @list = List.find(params[:id])
    @list.books.delete(Book.find(params[:book]))
    redirect_to :action => 'edit', :id => @list
end

Although the association method is delete. I don't the user thinking they are deleting the book, and want to convey to them instead that they are removing the book from the list.

I can think of these association related actions:

Remove - remove a record from a list.
Add - to add a record to a list.

Is there a consensus on action names for association related manipulations?

Not a universal consensus. I'd say there are different takes on best
or reasonable practice. One is to use ad hoc method names based on
what's happening, like lists/add_book. I don't think that's so
horrible, but it definitely lies outside any kind of CRUD and/or
RESTful convention and therefore won't garner you any of the possible
advantages of those conventions.

With CRUD edge cases generally, one thing you can do is force the
issue by asking: "If I *were* performing a CRUD operation, what would
it be? And on what entity or resource would I be performing it?"
Here, the answer is that you would be deleting (destroying) a Listing
-- not a List or a Book, as you point out, but an instance of the
connectedness *between* a list and a book.

So... you could have a listings controller, and in it you would do
(refined as needed):

   def create
     list = List.find(params[:list_id])
     book = Book.find(params[:book_id])
     list.books << book
   end

   def destroy
     # ditto, but remove
   end

There's a second stage to the process, if you want to do it, and that
is to also have a Listing model. If you feel it unnecessarily
complicates your associations to do it that way (it would generally
entail a has_many :through association), there's no overriding reason
to do it. You can still have a listings controller (and I've actually
been finding modelless controllers increasingly useful and RESTful).
But the Listing model is another potential aspect of thinking of the
listing itself as something that your application addresses, not
through book or list but alongside them.

David