2
\$\begingroup\$

I have a Rails app and in it I have two models, widget and votes. Votes are used to keep track of the desirability of a widget.

In my models I have:

class Vote < ActiveRecord::Base
    belongs_to :widget
end

class Widget < ActiveRecord::Base
    has_many :votes
end

I am trying to figure out the best way to route votes up and votes down. At the moment I am leaning towards this:

resources :widgets do
  member do
      put :vote_up
      put :vote_down
  end
end

Where the respective functions reside in the widgets' controller and it creates and saves votes in that controller. However, I realize that this doesn't really fit correctly with the MVC idea (votes should be created and built in their own controller). Is this acceptable or should I be doing something more like:

resources :widgets do
  resources :votes do
    member do
        put :vote_up
        put :vote_down
    end
  end
end
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

I would not create custom controller actions. up and down are attributes of a Vote, so I would do the following:

resources :widgets do
  resources :votes, only: [:new, :create]
end

And then send a POST to VotesController#create with params[direction: 'up'] and have an attribute on Vote called direction.

Then validate Vote#direction can only be up or down:

class Vote < ActionController:Base
  validates_inclusion_of :direction, in: %w(up down)
end 

Your check for this kind of routing decision is to run rake routes and make sure the route aliases make sense, in this case we are really creating widget_votes, which looks like:

         Prefix Verb   URI Pattern                             Controller#Action
   widget_votes POST   /widgets/:widget_id/votes(.:format)     votes#create
new_widget_vote GET    /widgets/:widget_id/votes/new(.:format) votes#new
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.