Shouldn't "rails plugin new" create an Engine by default?

I've been creating several engines for Rails lately and I found that having an engine class inherited from Rails::Engine is required if you intend to bundle some Sprockets assets.

So, shouldn't the template for "rails plugin new" change so that "rails plugin new some-example" would create something like:

lib/some-example.rb:

module SomeExample
     class Engine < Rails::Engine
     end
end

instead of an empty SomeExample module?

Maybe the "plugin new" could add some option like '--skip-engine' or disable it automatically if "--skip-sprockets" is used.

Make sense?

Kind regards,
Rodrigo.

It creates the lib/some-example/engine.rb file which is just as you described and then requires it in lib/some-example.rb. Shouldn't that be enough?

What version are you talking about? That doesn't happen on latest stable 3.2.5 here.

If that is already implemented in master, then great, I hope it to be backported to 3.2.6 when it gets released...

Thanks,
Rodrigo.

Yes. Just do "rails new plugin some_example --mountable".

You should also take a look at --full. :wink:

But my engines usually don't have any routes and even those who have are not mountable ones.

I'm just asking for an engine to be created even for non-mountable engines. I mean, as the default behavior of "rails plugin new plugin-name".

The "--full" will add integration tests which I also don't usually include in my gems.

Usually I want to bundle some JS libraries as Rails gems for easier reuse among my projects.

Basically, I'd like "rails plugin new plugin-name" to be equivalent of "rails plugin new plugin-name --full -T".

Does it make sense?

Cheers,
Rodrigo.

It’s a “rails plugin new” not “rails engine new”.

It doesn’t create a default Engine because not all plugins are engines.

If it’s an engine and not just a plugin/railtie you would normally want the “–full” option.

If not, just create it. It’s only 4 lines of code.

I’m not that lazy for avoiding to type “–full -T -O” every time I
create a new gem.

By the way I don't get why 's.add_development_dependency "sqlite3"'

is added to gemspec when -O is specified.

The problem here is that it seems inconsistent to me for a plugin

not to be an Engine. I don’t even understand why we have so many
concepts for extending Rails, like plugins, Railtie and Engine.

I guess it would be better to provide a single approach for

extending Rails 4.

In Rails 1, you could get an app-like tree in your plugin and they

would be automatically added to the Rails application. It still
seems to be the case for generators, for example:

http://guides.rubyonrails.org/plugins.html

But then, things changed a lot and what Rails 1 used to call a

plugin seems to be what an Engine currently is:

http://guides.rubyonrails.org/engines.html

Except that the Engine API is better designed than plugins were by

that time.

But it doesn't seem consistent to me that you can just drop

generators to lib/generators in your plugins, but can’t drop your
assets in lib/assets.

So, I guess that what I'd really want is to always create engines

and call them plugins.

I can't really understand why you consider useful to have plugins,

engines and railties as separate concepts.

Best,

Rodrigo.

One word: Modularity

If it’s a simple plugin, it doesn’t need to be a Railtie and inserted in rails

If it’s something that extends rails/AR it can be a Railtie and take advantage of that.

If it’s an engine then it makes sense to add the Engine and have the extra tools Rails::Engine provides.

It’s a simple question of remaining flexible to every type of plugin and not add extra unnecessary code.

One word: Modularity

If it's a simple plugin, it doesn't need to be a Railtie and inserted in rails

Could you please explain the differences about this and a regular Ruby gem?

If it's something that extends rails/AR it can be a Railtie and take advantage of that.
If it's an engine then it makes sense to add the Engine and have the extra tools Rails::Engine provides.

What kind of improvements/benefits would you expect by using the former instead of the latter?

If there is no real benefit, it would be better to always create an engine and avoid user's confusion.

The same rails guides like you pasted before shows a simple example of
"just a plugin" when it just extends the core class String.

As for the differences between Railties and Engines, I'll quote the
docs (http://guides.rubyonrails.org/engines.html):
"A Rails::Engine is nothing more than a Railtie with some initializers
already set. And since Rails::Application and Rails::Plugin are
engines, the same configuration described here can be used in all
three."

And extracting from the Engine doc:
"it will automatically load models, controllers and helpers inside
app, load routes at config/routes.rb, load locales at
config/locales/*, and load tasks at lib/tasks/*."

I think it will also add lib/assets to the assets path nowadays, but
the doc might be outdated.

The same rails guides like you pasted before shows a simple example of
"just a plugin" when it just extends the core class String.

I asked exactly what is the difference between this and a regular Ruby non-Rails gem.

As for the differences between Railties and Engines, I'll quote the
docs (http://guides.rubyonrails.org/engines.html):
"A Rails::Engine is nothing more than a Railtie with some initializers
already set. And since Rails::Application and Rails::Plugin are
engines, the same configuration described here can be used in all
three."

And extracting from the Engine doc:
"it will automatically load models, controllers and helpers inside
app, load routes at config/routes.rb, load locales at
config/locales/*, and load tasks at lib/tasks/*."

I think it will also add lib/assets to the assets path nowadays, but
the doc might be outdated.

Assets are correctly processed by engines. But the explanation above didn't talked about what a Railtie really is. What would it be useful for? They only explain what an Engine does.

http://api.rubyonrails.org/classes/Rails/Railtie.html
"if you need to interact with the Rails framework during or after
boot, then Railtie is needed"
It shows examples of how to use a Railtie too.

There is no real difference between a non-rails gem and a basic
plugin. It's just pure ruby that gets loaded automatically for being
in the plugins directory.

Go to the code and you can always have the most updated documentation
explaining these things:
https://github.com/rails/rails/blob/master/railties/lib/rails/engine.rb
https://github.com/rails/rails/blob/master/railties/lib/rails/railtie.rb

But this is not a core issue.

The point I'm trying to make is that there is no need for exposing so much details to extension developers.

I'd prefer Rails 4 to only provide a single generator for an engine that would fit all other cases covered by plugins and railties.

You don't have generators for Metal or other lightweight controller. Why would you have for a lightweight Engine?

This will just confuse extension developers for no sensible benefit in my opinion.

The point I’m trying to make is that there is no need for exposing so much details to extension developers.

There is. Engine has a longer initialization process, more objects involved, etc. Why would you submit your app to a longer initialization process when there is no need to?

Railties provides all the tools you could use to customize a Rails application.

An Engine is a Railtie with all the capabilities you would have in an Application (app, assets, routes, migrations, etc).

All these things are plugins. A gem is how you package a plugin.

But the explanation above didn’t talked about what a Railtie really is. What would it be useful for?

Read the Railtie docs or search for examples on github.com, there are plenty.

By the way I don’t get why ‘s.add_development_dependency “sqlite3”’ is added to gemspec when -O is specified.

It is a bug. Patches are welcome.

Thank you for your explanations, Jos�.

But don't you think that engines should be created by default by the "rails plugin new" command as I expect them to be more commonly used than railties or plugins?

This is similar to Rails Metal. You can get a lighter controller using lower-level classes instead of ActionController::Base for faster responses but you won't find generators for Rails Metal controllers.

I'm just talking about defaults here. Maybe engines should be created by default and disabled with --skip-engine in Rails 4. Or maybe Rails 4 could add a new "engine" command?