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 ??