views:

193

answers:

2

Hello,

I have three models that can all have a Review and each review must belong to a User. I am using polymorphic associations :as => :reviewable but I am not sure where I should put the logic for creating a review for each model. I would assume that the CRUD for each review should be handled by the reviews_controller (or nested attributes? in the other controllers?), but then how do I associate the review with each model ?

I couldn't find any examples of model/view/controller on google, maybe that would help a lot in clearing out things.

Thanks, Cezar

A: 

Since it's an update to the model, it's easier to go through the model's controller. Plus then there is no mistaking which model the review belongs to.

Take a look at what acts_as_commentable does. It might be easier to repurpose than to roll your own.

http://github.com/jackdempsey/acts_as_commentable/tree/master

Sarah Mei
+1  A: 

The problem with handling the object within the reviewable objects' controllers is that you'll find you wind up repeating a lot of the same code in each of the controllers. Moreover, where do you put the code? Either you wind up with some seriously heavy action methods (by piggy backing on your 7 existing actions) or you start creating actions like

new_review, delete_review, etc

which is not RESTful and is a serious code smell begging for its own controller.

Therefore, for something like this I'd consider having a review controller and either adding parameters to the url or using hidden fields to indicate what object the review belongs to:

<%= f.hidden_field :reviewable_id, :value => @object.id %>
<%= f.hidden_field :reviewable_type, :value => @object.class %>

This is particularly useful if there is any other work that needs to be done on the review object (such as save the current user as the author, etc.), as it keeps all the logic that can't be pushed out to the model in one place. Just be sure to scope the associated model correctly and ensure it belongs to the user, otherwise users can tamper with the URL and add reviews to whatever they want (of course that applies anywhere you select an object from user submitted data).

However, if the review object is very light-weight and doesn't require any extra processing (ie just a simple assignment of the posted data to the object) then you might want to take a look at using Rails 2.3 and it's nested object support.

luke_randall