views:

960

answers:

5

It is good practice to shift logic from the controller into the model. But in any complex system, this invariably leads to a very large file even if a majority of the methods are one liners as per the Rails Way.

I've resorted to splitting up models into other modules and including them in the original model, for example, model_flags, model_validation, etc. Anyone has a better way?

A: 

Modules sounds sensible. I wouldn't extract the method calls (validations, callbacks, plugins etc) into modules, though, I'd limit the extraction to my own methods.

And as always, it would help if you posted some sample code. I find it hard to imagine a generic strategy to clean up models, it depends on the nature of the code.

August Lilleaas
Well, that's the thing; I don't really have a strategy. Currently, I'm simply dumping methods from file to another, which doesn't feel very rails-ish, which is why I'm here to find out what the best practice is. Cheers =)
Jaryl
+4  A: 

I wouldn't do this for a few reasons.

First you violate the assumption that things will be where they should be which is probably the biggest bonus to rails in the first place. A new person can walk onto your project and navigate it quite easily if you stick model stuff in your model. If you pull it out you just add a delay and some confusion particularly if the only logic for removing something to a module is to reduce the model size.

Second you gain almost nothing from it and you lose something. File size doesn't matter these days when almost all editors and IDEs ease the navigation pain of large files. Moving stuff to a module actually takes some of this modern ease away and will require you and your colleagues or future maintainers to jump around several more files while working on one model.

That said I suspect what the hardcore rails best practice posse will tell you is that if your model is that large and complex then your design is flawed and your model is probably representing several things that could be made into separate models rather than modules.

srboisvert
Most of the behavior in Rails cannot be found 'where they should be'. Plus, by including modules into the main model file, you're already telling others where to look.I agree that navigating large files aren't that difficult, but how do you split up your models? What type of methods go first?
Jaryl
I don't split up my models. I vacillate between organizing them by functionality and alphabetically but i don't really worry that much about it.I agree with nakajima that you should pull out shared and reusable functionality where possible but more for the sake of DRY and good design than length.
srboisvert
+1  A: 

Having no knowledge of your object model, it's a bit harder to advise, but I'd say that if you're absolutely convinced that all of the validations/associations/callbacks need to be in that place, there are still ways of factoring out common behaviors. So while I wouldn't just move a big chunk of code out of one file and into another, where it just re-opens the class, I would say that using modules/plugins to describe common types of behaviors is a good idea.

For example, if you're building a Facebook-esque activity feed, and everything needs to generate "events", then maybe you'd want to move that "Eventable" behavior into a module, which when included, defines the associations/validations/etc. I'd say that approach would actually enhance the clarity of your code, since manually specifying those associations everywhere isn't nearly as expressive as declaring something as Eventable, nor is it as safe (you'd be duplicating logic in a bunch of places, and when the logic changes, you know the rest...)

All in all though, I'd say take a big look at your object model. In your test suite, if you notice that all of your tests require a lot of setup, that can be a good indicator that you're missing something in your object model. Again though, some sample code would be great.

nakajima
A: 

Don't, the MVC pattern says to put all your business logic in the models so this is a good thing (see Skinny Controllers, Fat Models).

Lolindrath
+2  A: 

Well, I wouldn't say that any of you are wrong to put everything in one model, but I think it is also quite valid to be able to separate various concerns. It is a trade off in the very least.

And I'm posting an answer to my own question, as I have found the Rails Way to do just that: http://github.com/jakehow/concerned_with

More information can be found here: http://m.onkey.org/2008/9/15/active-record-tips-and-tricks

Jaryl