I have a rails engine I'm developing. This is my first one, besides the example in rails documentation, so I don't have a good ref on what works. It has a partial that i'm requiring the Application to render.
<%=render partial: 'my_engine/foo/bar'%>
That works fine. And i understand why i need to reference the partial through the engine name space.
But within the partial, i apparently have to use the name space as well. So when i render a photo
<%= image_tag('my_engine/addphoto.jpg') %>
that is counter intuitive based on the documentation. Am I doing something wrong, or is just the way it is?
Okay thanks to Rich Peck I think I understand better. Let me enumerate so you can correct me if I'm still confused.
I was confused as to how the Namespace is generated for the engine. I was assuming that the structure generated the name space, and that when you were inside the engine, you would operate just as if you were in a normal app. And the namespace was automagic:).
But if I understand correctly the name space for the rails component is generated by encapsulating them in the :::: module EngineName which is taken care of by the generators, but if you're creating the file manually, then you need to add the encapsulation in the files. Since this was my first engine I didn't know that they were missing.
For the Asset pipeline the namespace is generated by the structure image/enginename/....
So even within the engine unless your inside the module, you have to honor the namespace EngineName::ModelName::Method.
The namespace isn't applied to the task file, doesn't seem to like being incapsulated in a module. But that is redundant anyway since the rake task already provide a namespace method.
Ala namespace :db do
I was also surprised to find that you need to manually include the namespaced application controller in the namespaced controllers ala
require_dependency "enginename/application_controller"
but as Rich says, the engine is just a glorified module, so I guess it needs a little help now and then.
And of course the Javascript files are isolated because they're only loaded when one of the pages from the engine are loaded, and NOT when a partial from the engine is rendered. You can have the user of the engine include the javascript file in their application.js, but then they need to be namespaced manually to avoid confusing them with similar JS from other sources. There's a good blog on actually doing that by Kenneth Truyers that I'd bookmarked for a future exercise, maybe I'll need to get to it now.
lso the locales are not name spaced, so you need to do that yourself. Simple to add :engine_name to the locale file hierarchy ala de: :engine_name :variables I would recommend adding a prefix to the engine name like x so that you avoid getting your engine locales clobbered by a user using the same name as a variable. So xAdmin: would be better then Admin: since it's likely someone like me would use Admin: as a variable for an admin function:) and discover that all the localization in your engines suddenly disappeared.
Rich, am I closer
Now to extend my question,
I'm not sure that the initialization files are namespaced. Does a enginename.rb file in the apps initializers directory overwrite one with the same name in the engine's initializer directory? I assume if it's true we can just use a different name in the engine initializer since I think it there are no real associations to the file name, just bookkeeping.
Now how to extend a model in the app.
So to add columns to a apps model is it okay to do this
in engine.rb (located in lib)
mattr_accessor :user_class
mattr_accessor :user_table
in the engine_initializer.rb
engine.user_class= 'User'
engine.user_table='users'
then in the migration
add_column Engine.user_table.to_sym, :attribute
add_index Engine.user_table.to_sym, :attribute,
name: "index_#{Engine.user_table}_on_engine_attribute".to_sym
which seems to work okay
But how do we add methods to the model. I'm having the user add require 'engine/user_include.rb'
Is there a nice way to do that