# Developing an engine: What should I keep in mind?

**URL:** <https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491>\
**Category:** Engines\
**Created:** [May 14, 2006, 7:05pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491 "2006-05-14T19:05:00Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 14, 2006, 7:05pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/1 "2006-05-14T19:05:00Z")

</div>

Hi all

I’d like to begin with clean development of engines that I will be able  
to re-use and give to the Rails community.  
Now my question: what should I always keep in mind when writing code for  
an engine? I’m thinking here about stuff like that I shouldn’t hard-code  
table names etc.

And by the way: Isn’t it quite dangerous to hard-code model names, too?  
We’re nearly forced to do this, I know, but it could be quite often the  
case that the name of an engine’s model is the same like the name of  
another model, right? That’s quite dangerous… :-/

Thanks for infos! 🙂  
Joshua

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 15, 2006, 1:30am UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/2 "2006-05-15T01:30:22Z")

</div>

What you should keep in mind when developing an Engine:

## Keep it focused

Don’t try and solve 1000, 100, or even 10 problems. Do one thing, pick  
one strategy, and do it cleanly and clearly.

## Convention over configuration

Don’t add configuration until YOU need it, and even then think hard  
about whether or not it’s the right thing to do. Engines aren’t  
all-terrain vehicles - they should expect to be allowed to do their  
own thing to the greater extent, and your application, being more  
flexible, should cope with how the engine works [1].

## Make it modular

Try and put code into modules wherever you can - it helps with  
namespacing, and makes it simpler to override code in the case of  
models.

## Document like your life depends on it

If you are anticipating that ANYONE else might be wanting to use this  
code, make sure that you’ve got a great set of documentation (READMEs,  
RDoc, the works) to support it. You’ll save yourself a lot of time in  
front of an email client if you do.

… those are a few things to bear in mind, I guess. But here’s the  
doozy:

## Screw the community - write it for yourself.

It’s only through need that you discover what features are really  
important, and only through the need for reuse that you get a deeper  
understanding of which aspects of your code can afford to be a bit  
more flexible. Write your engine with YOUR needs in mind, and don’t  
try and anticipate problems until you hit them yourself.

Once you have a solid understanding of what you’re trying to do, then  
by all means let other people in on the project. But always bear in  
mind that code is only really useful when it has a purpose, and if  
you’re not using it yourself then how can you really understand what  
it should do?

… OK, here’s some more practical advice:

- Put your controllers into modules.
- Provide a sensible set of routes for the user to use, and use them  
religiously for redirects and link\_to calls in your own views [2]
- Document! (Yeah, I already said that, but it’s crucial)
- Put model code in modules
- Try and provide a set of useful partials, rather than a smaller set  
of views, as these are easier to reuse.

Good luck!

- james

[1] People email me asking how to get the login engine to work with  
their application, which has been designed to use Account models  
rather than Users. The short answer is… you can’t. Sure, there are  
hacks and ways around this, but your life is a lot simpler if your  
application has been designed in harmony with the external code it’s  
going to interact with, rather than trying to shoehorn everything  
together after the fact. Don’t try and please everyone, because design  
by committee produces camels, not racehorses  
([http://www.pfc.org.uk/medical/mmacvw.htm](http://www.pfc.org.uk/medical/mmacvw.htm)).

[2] There’s no automatic mechanism for including routes with an  
engine, but simply provide some that can by copy-pasted into the  
application’s routes.rb file. That’s fine and possibly even  
preferable.

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 18, 2006, 12:55pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/3 "2006-05-18T12:55:46Z")

</div>

#if forum /\* May 14, 07:05 \*/

> Hi all
> 
> I’d like to begin with clean development of engines that I will be able  
> to re-use and give to the Rails community.  
> Now my question: what should I always keep in mind when writing code for  
> an engine? I’m thinking here about stuff like that I shouldn’t hard-code  
> table names etc.

I’ll dive in on this last question:  
There’s no need to hard-code table names, have a look at:  
user\_engine/lib/user\_engine.rb, notably this part:

# The names of the new Role and Permission tables

if ActiveRecord::Base.pluralize\_table\_names  
config :role\_table, “roles”  
config :permission\_table, “permissions”  
else  
config :role\_table, “role”  
config :permission\_table, “permission”  
end

IIUC you could override the actual table names by placing directives  
into $RAILS\_ROOT/config/environment.rb, like this:

module UserEngine  
config :role\_table, “my\_roles”  
config :permission\_table, “my\_perms”  
end

Then, when you actually come to use the table names, say for example in  
a JOIN thats tucked away in your code, you can pick out the table name:

```
UserEngine.config(:role_table)

```

and use it like:  
:joins =\> "INNER JOIN #{UserEngine.config(:role\_table)} ON " +  
“#{UserEngine.config(:role\_table)}.somefield = " +  
" some\_table.some\_column”

And if you want the the class name, you could do:

```
UserEngine.config(:role_table).classify

```

which would pick out “Role”

using these techniques, i believe you can decouple the table names and  
classes from your code.

Although, the class names may still conflict with other ones, if you  
choose generic names.

HTH at least a little.

–  
keys: [http://codex.net/gpg.asc](http://codex.net/gpg.asc)

[a] The Japanese eat very little fat and suffer fewer heart attacks  
than  
the British or Americans.

[b] On the other hand, the French eat a lot of fat and also suffer  
fewer  
heart attacks than the British or Americans.

[c] Conclusion: Eat what you like. It’s speaking English that kills  
you.

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 18, 2006, 3:16pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/4 "2006-05-18T15:16:40Z")

</div>

Thanks a lot for your input, Vincent. What you describe is a very  
fundamental part of developing an engine, I think. 🙂

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 16, 2006, 8:36pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/5 "2006-05-16T20:36:27Z")

</div>

Hey thanks a lot for this great points. 🙂 As a newbie I still got some  
questions though…

> ## Make it modular

How exactly would you do that? If you have a model models/my\_model.rb,  
where would you put the module’s code? Maybe under  
models/my\_model\_module.rb or so? And then just use include  
‘my\_model\_module.rb’ within my\_model.rb? Can you please give me an  
example for this?

> ## Document like your life depends on it

That’s a very good point. Is there further documentation how to document  
a Rails project/engine?

> - Put your controllers into modules.  
> Can you please give me an example for this, too?

> - Provide a sensible set of routes for the user to use, and use them  
> religiously for redirects and link\_to calls in your own views [2]  
> Why no simply use the standard route? If I write other routes - won’t  
> this mean more configuration than convention?

> - Try and provide a set of useful partials, rather than a smaller set  
> of views, as these are easier to reuse.  
> You mean that someone who wants to alter the design maybe just can  
> include some partials he likes and rewrites some he needs else?

Thanks a lot for your great answer. 🙂

---

<div class="post-metadata">

**Author:** ![josh](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/45deac/32.png) [@josh](https://www.ruby-forum.com/u/josh)\
**Post date:** [May 18, 2006, 3:22pm UTC](https://www.ruby-forum.com/t/developing-an-engine-what-should-i-keep-in-mind/60491/6 "2006-05-18T15:22:37Z")

</div>

Please do be careful before you make things _too_ generic, though.  
Develop only what you need, and then abstract afterwards.

- James
