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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With