views:

146

answers:

2

Hello everyone,

I have a Rails application with several models-views-controllers which have some similar characteristics, for example 5 different models can be commented on, voted on or tagged, I am also heavily using external plugins.

At the moment I introduced comments, votes, tags, etc. only to a single model (and its view and controller). However, now that I am happy with the results, I want to cut out this common functionality from the particular MVC of one model and allow access to it from all other models.

Some questions before I start doing this (and maybe some general advice will also be great):

1 - How should I go about it? I was thinking creating a module in "lib" directory (is it the same as mixin class?) and then moving reusable view code to common partials. What about the controller code?

2 - As I was just learning Ruby on Rails during the coding of the first model, I went with a probably incorrect way of adding a bunch of methods to the controller. I have a method that adds a comment (addcomment), adds a vote (addvote), etc. All these methods require non-standard (non-RESTful) routing via :collection. From what I understand, the correct way would be to move comments controller functionality to its own controller and access via standard RESTful routes. Is this what I should be doing?

3 - Many plugins (eg. act_as_commentable) do not explicitly require loading a Module, just a line "act_as_commentable" somewhere in the Model. Can I use something like this for my common functionality? How does it work?

+1  A: 

For repeated model code, put it in a module in the lib directory.

For controller code, put your duplicate code in ApplicationController.

For your view code, use partials.

Mike Trpcic
For controller code can I also put it in a module? (for example CommonModel for model and CommonController for controller?) Some of my Classess won't need the extra controller methods.
Vlad
+3  A: 
  1. A simple way is to split the code into modules and use mixin. A better way is to write your own plugins for your common code.. like act_as_commentable you can learn about it here: http://guides.rubyonrails.org/plugins.html

  2. The correct way is to do a comments controller, and have it nested to your models, giving a restful routes like this: /mymodelname/1/comments. An easy way to make such controllers is by using inherited_resources plugin. scroll down to the "Polymorphic belongs to" section- there is a comments controller example

amikazmi