Extend Model in Plugin with "Has_Many" Using a Module

Extend model in plugin with has_many using a module

I think this should work

module Qwerty
module Core
module Extensions
module User
# Instance Methods Go Here

# Class Methods
module ClassMethods
def relate
has_many :hits, :uniq => true # no method found

before_validation_on_create :generate_code # no method found
end

def something # works!
"something"
end
end

def self.included(base)
base.extend(ClassMethods).relate
end
end
end
end
end

The old code is wrong cause the validation and the association are called upon module loading, and this module knows nothing about ActiveRecord. That's a general aspect of Ruby, code inside class or module bodies is called directly when loaded. You don't want that. To get around that you can use the above solution.

Polymorphic :has_many, :through as module in Rails 3.1 plugin

It turns out that adding :class_name to both :has_many definitions will actually work (someone commented on that, but they deleted their comment). It didn't work in my non-simplified program because of something else in my program that was causing a cascading error that SEEMED to be local to the :has_many definition.

Short story: It was a lot of trouble for something that wasn't actually a problem. Blech

How do I extend a model in Rails?

The problem you have now is that you are extending your class, not including a module into it, so the Sicada::Extensions::UbiquoUser#included method never gets called.

To fix this, change this line:

UbiquoUser.send(:extend, Sindicada::Extensions::UbiquoUser)

to

UbiquoUser.send(:include, Sindicada::Extensions::UbiquoUser)

How to extend a model in a Rails engine from another Rails engine?

Turns out I can do the following in the tickets_engine:

# contrived_app/vendor/plugins/tickets_engine/config/initializers/concert_extensions.rb
# or
# contrived_app/config/initializers/concert_extensions.rb
Rails.logger.info "\n~~~ Loading extensions to the Concert model from #{__FILE__}\n"

Concert.class_eval do
has_many :tickets
end

Personally, my preferred method is to extend the concert model from the tickets_engine, but load order and dependencies are important. i.e. tickets_engine would need to add a dependency on the concerts_engine in it's gemspec, and concert_engine would need to be loaded before tickets_engine.

How to extend a class from an initializer and have it reload in development environment?

environment.rb

config.to_prepare do
User.send :include, Qwerty::Core::Extensions::User
end

The code is the block is run before every request in development mode and once in production mode.

Extend instance method of model

include is a private method and cannot have an explicit receiver. You can get around this limitation by using send:

MyModel.send(:include, InstanceMethods)


Related Topics



Leave a reply



Submit