RESTful CRUD-Controllers by simulating trivial resource


I would like to know your opinion on the following idea:

In order to keep controllers normalized you often have to introdruce
new models whose CRUD-actions replace non-CRUD-actions. But sometimes
the resulting resources can be nearly trivial. Example: User

=== RPC approach ===


def activate
  @user = User.find_by_activiation_ticket(params[:activation_ticket])
  @user.update_attributes(:activated => true)

You *could* refactor this to REST like so:

=== REST approach by introducing new resource ===

- Create model UserActiviation:


class UserActivation < AR
  belongs_to :user

- Create CRUD-Controller UserActivationController.

- Database overhead to find out if a user is activated
- Seems to be a bit overkill, if you ask me.


=== REST approach by simulating the existance of a resource ===

- *Only* create a UserActivationController


class UserActiviationController < AppController
  def create
    if params[:user_activation][:user_id]
      @user = User.find(params[:user_activiation][:user_id])
      @user.update_attributes(:activated => true)

That way your api is stricty RESTful. But you do not have to pay the
cost of introducing nearly trivial models.

What do you think?


REST doesn't imply having to model *everything* to CRUD, hence
support for member functions.
An example from my routes ...

  map.resources :subscriptions, :path_prefix => ':locale/
admin', :controller => 'admin/subscriptions', :name_prefix =>
'admin_', :member => { :upgrade => :put, :downgrade => :put} do |
    subscription.resources :payments, :controller => 'admin/
payments', :name_prefix => 'admin_'

You could implement yours like this ...

Class UsersController.rb < AC::Base

   #CRUD actions here

   def activate
     @user = User.find_by_activiation_ticket(params[:activation_ticket])
     @user.update_attributes(:activated => true)


your route:

map.resources :users, :member => { :activate => :put } #post / get if
u like

and invoked with users/1;activate

namespaced-controllers , anything's possible with REST and routes,
without having to add additional overhead.

- Lourens


thanks for your answer. You're right: The original approach does not
necessarily conflict with REST and resource orientated routing.

But I still think that there are situations where you might want to
provide a strict CRUD-interface for your controllers. For example to
allow easy integration with ActiveResource (which does not really allow
invocation of actions identified by an ";ascept"-syntax, right?).

Maybe my example was a bit weak, since user activation will not often
have to be invoked by webservices. The main idea of my original post
was the following: Since REST is all about representations there is no
absolute need to introduce a model for every controller. If these
"virtual" resources are accessible like all the others from outside,
the internal way of storing them does not matter.

And this might be an interesting thing to consider, since some of
REST's downsides that I see relate to database issues.