Topic: Business Logic

Dear All,

I am still relatively new to rails.

I am trying to figure out where to put general business logic, not domain specific logic.

I know the usual aswer to this is in the controller.
The controller in many other MVC applications, as far as I understand it, is kind of like the user event loop, it connects the model and the view passing data between them and executing actions. So it does not feel right to me, to put 1000 lines of what I would call business logic in a controller method (an action).

In addition I can use this code elsewhere, it could be used in other projects, and in my view should remain separated from the controller code, so it can be swapped in and out.

If i create my own business directory in rails and put my code there, then it works, but does not reload, so WebBrick must be restarted with every change. include "reloadable" does not seem to work in this instance.

My head must be stuck in Java, because there must be an easier way to have non controller business logic and yet still have separation of concerns, and also have the quick turn around that is so nice in Rails.

Help me Obi-wan, help me.

cheers,
J

Re: Business Logic

I've almost never seen business logic put into the controller, in any MVC environment.  Business logic, almost by definition, belongs to the domain and thus the model.

Yes you end up with some business-related routing logic in the controller, but that should be as minimal as possible.  (Ie logic related to how errors/non-routine processes are captured and resolved.)

My RoR journey  -- thoughts on learning RoR and lessons learned in applying TDD and agile practices.

Re: Business Logic

I'm curious just what kind of business logic this code you have governs.  Ruby has taught me that nothign should ever be consigned to 'misc' or 'general' but that everything has it's place and, with enough pondering, it can be structured in an efficient and easy-to-follow way.  So I'm curious whether this code applies to models, to user interactions, to multi-page forms or something else.

No matter what kind of code it is though, anything that's over thirty lines should probably be in it's own module.  Especially if it's reusable it should be encapsulated (perhaps even broken up into several modules) and included in controllers or models when necessary.  I've done this with collections of redirect methods and with libraries that help my apps connect to outside applications.

regarding your question of code not reloading:  there's a 'load' method that works just like 'require' except that it forces reloads whenever it's specified.  You might want to try that out!

Re: Business Logic

Usually business logic acts upon data that is stored in a database, therefore the model containing the data should contain the logic. If the logic isn't acting upon data that needs to be stored in a database, you can still create a model for it, just don't have it inherit from ActiveRecord.

Any class containing 1000 lines of code - not to mention a method - should raise alarms. Classes and methods should be small and understandable, that is the way of object-oriented programming. If it is too big, extract it into its own class or module as Danger suggested.

Railscasts - Free Ruby on Rails Screencasts

Re: Business Logic

Coming from a Java background like you, I've found that a lot of the non-domain logic you have in Java kind of disappears.  Things like mapping Struts ActionForms to POJO's just aren't an issue anymore.  I'm not sure if you are trying to solve a problem, or just thinking ahead. If it's the later, then don't stress, just try it out and things will find their place.

Re: Business Logic

Thanks guys for all the responses.

"Load" is definitely useful, I can put all my "business logic" in its own space. Thanks!

For the curious: this one project is the only project of 6, where there is excessive calculation, which does not seem to fit in the domain or controller. Without spaces and comments its about 400 lines. I am refactoring for better testing - so that may blow out a bit.

Basically I am assigning people to groups, priority matrices have to be built, so as to stop people being with the same people in a group many times. I autogenerate groups for a particular academic course, so for example 52 people have to be divided up into groups of 4. People are assigned to groups based on who they have been with and the current teams. I found the proper solution to not be as simple as I intially thought.

Bits of it will probably migrate to the domain (ActiveRecord and non-ActiveRecord classes), but for the moment i am happy with the performance, with tens of thousands of calculations and manipulations, its under 10 seconds for 30 people.

Thanks for all your answers, very helpful !!!

Are there any "standards" in Rails to intercept methods?

I am throwing a filter into my application controller, with which I hope to intercept the methods in the business code (and anything else I see fit)  above, to dynamically add logging, profiling, transaction/rollback, singletons etc. The dynamism and beauty of Ruby is living up to its name.

cheers,
J

Re: Business Logic

johnmshea wrote:

"Load" is definitely useful, I can put all my "business logic" in its own space. Thanks!

Just watch out for when you move into production so the files aren't reloaded on every request.

johnmshea wrote:

Are there any "standards" in Rails to intercept methods?

Something like this is mentioned in [url=http://www.rubyist.net/~matz/slides/rc2005/mgp00034.html]Matz

Last edited by ryanb (2006-09-06 14:10:22)

Railscasts - Free Ruby on Rails Screencasts

Re: Business Logic

Cheers, Thanks Ryan.
J