REST - Some doubts

Hi,

I recently started using rest for building some new rails apps. I find
it great and clean, but when I started a big project some days ago some
doubts come to my mind.

First of all, after implementing the user management and authentication
system (which in my case is quite complex) I noticed my routes.rb file
was already fairly big. It seemed to be reasonable to me since I have to
perform lot of operations on the users of my app, especially form the
admin namespace, but the fact that I just started the project and I
already have this huge routing files scares me.

Moreover, I’m used to have a lot of helper actions to handle calls to
link_to_remote (used for example to dynamically change form fields based
on user input). Some of these calls can be handled by the classic REST
actions with respond_to, but for others it just makes sense to have a
custom action, and this forces me to insert a custom route every time in
my routes.rb file.
The same applies to small actions like “activate” or “block” for users.
I know that in the REST way of doing things this could be done by
creating separate controllers, but this seems stupid to me (especially
in my case, I’ll be force to create one such controller for each user
type, with subsequent route definition).

I hope someone can help me clarify those doubts.

Thank you in advance (and sorry for the english, it’s not my native
language)

Hi Simone,

In your “activate” and “block” actions can’t you just use the common
“update” action, just passing the necessary parameters?

It would be as simple as receiving an “user[ativated] = false” from
the request and you could probably reuse the already implemented
“update” action in your controller. I’ve killed many unecessary named
routes by using the already implemented actions and parameters.

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Fri, Jan 23, 2009 at 5:10 PM, Simone G.

Hi Maurício, thanks for your reply.
In fact I can’t just reuse another action because it’s not just a matter
of changing a field in the database (which in that case update could be
ok), I also perform some background operations like sending emails and
updating other protected fields of the model (like date of activation or
removing activation code). To do that I need to call a model method like
user.activate or user.block, and it would be a mess probably to
integrate this behaviour inside the update method.

You don’t need to integrated it at the update_attributes method,
here’s an example:

class User

def activate( save = true )
##do activate stuff and save the model if save == true
end

def activated=( new_value )
selc.ativate(true) if new_value == true and
self.read_attribute(:ativated) == false
end

end

You would just pass the activated attribute value and “activate” or
deactivate the user as required and without writting a new action.

But if something like this doesn’t work for your model, i guess you’re
out of luck.

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Fri, Jan 23, 2009 at 5:29 PM, Simone G.

Well, mine is already big, 264 lines and counting.

The first thing that i did was to group as many controllers with only
the default routes as possible, as in:

map.resources :users, :clients, :products

They used to be in separate places and where making the file bigger
for no reason.

Another thing was to move the “admin” controllers basic config to a
block, and just call the block when i needed to configure an admin
controller, here’s a sample:

admin_configurer = Proc.new do |resource_name, options |
options ||= {}
map.resources resource_name, { :path_prefix => ‘/manage’,
:name_prefix => ‘manage_’, :controller => “manage/#{resource_name}”
}.merge( options )
end

admin_configurer.call :deactivated_users, :member => {:define => :put}
admin_configurer.call :products

I removed a lot of uneeded lines with this, but I still got a big
routes file, i guess it’s something we’ll need to live with. My next
idea was to separate the routes in “areas” and then get each of those
areas in a separate file and eval it at the routes.rb “draw” call, but
I haven’t really done that as i think it isn’t needed, at least for
now.

Maurício Linhares
http://alinhavado.wordpress.com/ (pt-br) | http://blog.codevader.com/
(en)

On Fri, Jan 23, 2009 at 5:45 PM, Simone G.

Thanks again Maurício, good advices as before. Maybe I was too used with
the classic small CRUD routing idea, but I guess that as long as it
doesn’t create any slowness problem probably the big routes file is
unavoidable for complex applications.

Sorry to butt in, and this is unconfirmed info, but I swear that I
heard a rumor of Rails 3 (the new Rails/Merb combo powerhouse) support
for Maurício’s concept of routes “areas.”

It would be a nice way to separate things out and lazy load only what
you need at run time. Having a routes folder with specialized routes
(even that dreaded default when needed) would be sweet. Routes do get
rather large even on some simple apps and it would be nice to have a
way to trim things down.

+1 for that idea, Maurício.

On Jan 23, 4:02 pm, Simone G. [email protected]

Not out of luck I’ll say, that’s a good idea, thanks for the tip. As for
the routes file becoming big, do you have some idea about it?