Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should you use RESTful controllers in a Rails app, and when should you not?

I'm looking for guidelines on when to know when a RESTful approach to a model and it's associations is proper, and when it's not. Perhaps it's the nature of my current application, but I'm finding that simple models with no associations work well with REST, but complex models with many has_many assocations really seem to complicate the view and the setup required in the controller. form_for calls start to become especially complicated.

Or perhaps it's my neophyte understanding. I've been doing Rails for over three years now, but REST and form helpers together seem to mystify me.

like image 677
jbwiv Avatar asked Mar 25 '09 04:03

jbwiv


People also ask

What is RESTful in Rails?

REST is an architectural style(Wikipedia) that is used in Rails by default. As a Rails developer, RESTful design helps you to create default routes by using resources keyword followed by the controller name in the the routes.rb file resources :users.

What does controller do in Rails?

The Rails controller is the logical center of your application. It coordinates the interaction between the user, the views, and the model. The controller is also a home to a number of important ancillary services. It is responsible for routing external requests to internal actions.


1 Answers

Make a resource of each top-level model in your system. By top-level, I mean models that are independent and have meaning outside of the associated model. Generally, that's most models. In the following example Position and Candidate are top-level. You could consider Candidate to be composed of PastEmployment and positions to which she has applied. Applications to positions and prior work history can be accessed through the Candidate resource, since they don't exist on their own.

Models

class Position
  has_many :candidate_positions
  has_many :candidates, :through => :candidate_positions
end

class Candidate
  has_many :candidate_positions
  has_many :positions, :through => :candidate_positions
  has_many :past_employments
  accepts_nested_attributes_for :past_employments
  accepts_nested_attributes_for :candidate_positions
end

class PastEmployment
  belongs_to :candidate
end

class CandidatePosition
  belongs_to :candidate
  belongs_to :position
end

Routes

map.resources :positions
map.resources :candidates

Use a non-resourceful controller for interactions with the user that span models. For example, if you wanted to have a HomeController that shows available positions as well as recent candidates, that would be a new, plain controller. If you want to edit any of the information on this controller, cool! You already have controllers available to handle the form posts, that will automatically be wired with <% form_for @candidate %>. You can render your collection of positions with <%= render @positions %>, and because you've made them a resource, Rails will know to look in views/positions/_position.html.erb for the appropriate partial.

The end result should be that you're never writing logic to handle the persistence of an object in more than one place. That's when controllers get complex and forms get out of hand. It also means that Rails and external systems know where to retrieve and store objects. Same URL, same controller, just a different format.

like image 120
Sam Coles Avatar answered Nov 12 '22 12:11

Sam Coles