views:

456

answers:

2

Hi, I've written a rails app that follows the regular directory structure (model code in models, controller code in controllers).

But I'm now working on a new feature and for that I have written some (what I would call) "service" code.
The new feature is to import some data into the system, at the moment it's two classes to do the importing but could expand to more.

I don't believe the new code belongs in model as it's not modelling any object (it's not directly related to any single object either. I certainly don't think it belongs in controller either as it's not presentation logic.

So, I've created a "app/services" directory and put it in there. I've also created a "test/services" directory where I have put my tests.

All well and good I thought but when I run 'rake:test' or 'autotest' my new services tests are not run.
Now I expect there is a way to make rake pick them up but is this a warning flag that I have done something wrong?
Is there some other place the code should live or am I somehow not doing things "the Rails way"?

Generally whenever I've hit a problem like this before I've usually found that rails had a solution already, but I was not aware of the convention. Is this one of those cases?

+14  A: 

This is what the 'lib' folder is for.

The lib folder is in the automatically looked up path, so you can have

class MyFoo
end

in lib/my_foo.rb and then just by calling

MyFoo.new

from a controller the code will be loaded without you needing a require 'my_foo'

Gareth
Thanks, where would the tests go for this though?
Darren Greaves
Your tests can still reside in your /tests folder in the root of your app. You just need to do a 'require <lib>' at the top of the test. So if your file is "service.rb" in the lib directory, just "require service" in your test.
mwilliams
Thanks, have now moved them into a directory under lib (I made them into a module too).Rake still doesn't pick up my tests but that's another problem I guess.
Darren Greaves
+1  A: 

./lib is definitely the place to go.

Another place to put this is in the initializers directory under config, depending on what it is your doing. You might also consider making the whole thing into a plugin, but if it's a small amount of functionality, it probably isn't worth it.

Cameron Price