custom REST actions, best practices?

Hi,

I really like the benefits of using REST for my routes and controllers,
but I can't help but feel a little restricted. I'm trying to figure out
the best way to match together my actions with views.

For example I'm trying to put together a Profile page for each of my
users. I've got a User model, a Profile model, and models for things
that belong in the profiles, like Pictures. Each profile would have
separate views, i.e. a page with the basic profile information (name,
avatar, interests, etc) as well as a Gallery page that show the pictures
that belong to the User. I'm trying to figure out the best way to tie
these different pieces of the Profile into my RESTful controller.

My initial thought would be to use custom actions. "show" would show the
profile information while "gallery" would be used for the pictures. But
semantically speaking, wouldn't "gallery" be incredibly similar to the
"index" action of my Pictures controller, but just restricting it to
that user's pictures? Does it make sense to build my own Gallery
controller, despite the fact it'll just be an extension of the Profile
controller?

I guess my questions are: when does it make sense to use custom REST
actions, and what are the best practices for incorporating similar
actions into multiple views while keeping things as DRY and RESTful as
possible?

Thanks.

I know how you feel about this as I experience the same problem. One bit
of advice is that if you find yourself needing more than 2-3 custom
actions then something is wrong with your design (i.e you need to
rethink resources). However, a custom action or two is usually fine.

As for incorporating multiple models into a single view, I would
recommend using partials. Store the pertinent part for each segment of
the view into partials which reside in the appropriate view folder for
each model and then decide which controller will house the combination
of all the partials. Then just devise a layout and then render all the
relevant partials onto that layout for the action.

Just some thoughts. In REST I first think in terms of resources and URLs, then the controllers and actions follow and I may reuse some stuff.

In you example you have already figured out the resources, right, now the URL may be something like this

    /users/{user_id}/gallery

Once you know that, the way you're going to implement it suggests whether you want a :member or a nested resource or a named route, ....

If you think at the implementation level that's essentially PicturesController#index plus scope I think it is a good practice to reuse it behind the scenes. In those cases I use this pattern for a ProjectController that takes advantage of the fact that associations are proxy objects:

     before_filter :determine_scope
     before_filter :find_project, :only => ...

     def index
       @projects = @scope.find(:all)
     end

     def destroy
       @project.destroy
       redirect_to projects_url
     end

     def determine_scope
       @scope = Project
       if params.key?(:customer_id)
         customer = Customer.find(params[:customer_id])
         @scope = customer.projects
       elsif params.key?(:user_id)
         user = User.find(params[:user_id])
         @scope = user.projects
       end
     end
     protected :determine_scope

     def find_project
       @project = @scope.find(params[:id])
     rescue ActiveRecord::RecordNotFound
       redirect_to projects_url
     end
     protected :find_project

-- fxn

Thanks for both of your suggestions. I realize I need to do a bit more
planning and a bit more research before diving into this.

having
map.resource :account do |account|
  account.resource :gallery
end
in your routes you'll end up with

a page with the basic profile information (name, avatar, interests, etc)

get /account, mapped to AccountsController#show

as well as a Gallery page that show the pictures

and get /account/gallery mapped to GalleriesController#show

fairly restful and no custom actions at all

I have a problem with understanding rest routing for custom action
with many parameters , e.g :

Is this correct in restful convention ?
  map.assign_template '/sections/
assign_template/:section_id/:parent_id', :controller =>
'sections',:action => 'assign_template'

or it should maybe have sth like :method=>:get at the end ??