Overriding model associations

I seem to recall reading that engines will not allow you to override
your plugin models in the main application. Is that true? If so, is
there a simple hack that would allow me to override an association?

I have the following defined in my plugin

class Tag < ActiveRecord::Base
has_many_polymorphs :taggables,
:from => [:products],
:through => :taggings,
:dependent => :destroy
end

This is fine except my host app uses has_many_polymorphs (HMP) plugin
for tagging of other stuff. The problem is the association needs to
include the additional classes in my main app. So I need something
app specific:

class Tag < ActiveRecord::Base
has_many_polymorphs :taggables,
:from => [:photos, :products],
:through => :taggings,
:dependent => :destroy
end

Obviously I don’t want to change this in the plugin. What are my
options?

Regards,

Sean

On Mon, Oct 08, 2007 at 01:36:32PM -0400, Sean Schofield wrote:

I seem to recall reading that engines will not allow you to override
your plugin models in the main application. Is that true?

It won’t work properly with autoloading. You’ll have to it manually.
Just put

require_dependency
“#{RAILS_ROOT}/vendor/plugins/my_engine/app/models/my_model.rb”

just before the class definition in RAILS_ROOT/app/models.

James, this seems to be a FAQ. Can you include it on the website’s
FAQ page? Thanks.

Regards,
Peter B.
Solide ICT - http://www.solide-ict.nl

Weird. I decided to test the default behavior before trying your
suggestion and it worked the opposite of how its been documented. My
app/models/Tag.rb loaded in place of plugin/models/Tag.rb. I can’ say
for sure which order the classes were loaded in but the end result was
that the associations created by the plugin version were ignored in
favor of the ones created in my app model.

Perhaps this is unique to HMP? In any event, its good to know the
workaround which I’m sure to need at some future point. I also agree
it should go in FAQ (along with a description of the load order for
views, helpers and controllers.)

Thanks for the help.

Sean

On Tue, Oct 09, 2007 at 10:16:00AM -0400, Sean Schofield wrote:

Weird. I decided to test the default behavior before trying your
suggestion and it worked the opposite of how its been documented. My
app/models/Tag.rb loaded in place of plugin/models/Tag.rb.

That’s correct, and as far as I know that’s exactly how it’s documented.
It will load that model instead of the one in your engine, as opposed
to mixing it in with the engine code, which is what happens with the
controllers and helpers. This means that any methods defined on the
model class in your engine will not be available from the application.

That’s why you need to manually add a require_dependency call just
before
defining your model. That way, the model class definition “opens up”
the
existing class from your engine. This is what happens automatically in
the case of Controllers or Helpers.

Hope this explanation is a little clearer,
Peter B.
Solide ICT - http://www.solide-ict.nl