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.

On Feb 23, 2008, at 4:25 , Bryan M. wrote:

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?

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

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

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.

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