Kris
Kris

Reputation: 19958

When extending an object at runtime how do I call a class method?

I'd like to extend an object (instance of ActiveRecord::Base) at runtime and call a class method (to add a has_many association). My ideal code would like as follows:

class User < ActiveRecord::Base
end

module Seller
  has_many :bookings, :foreign_key => :seller_id
end

module Buyer
  has_many :bookings, :foreign_key => :buyer_id
end

user = User.find(1)
user.extend Seller
user.bookings

Please note I do not want to include the modules in to the User class, I want to extend the behaviour of the a single user object, not all user objects.

Upvotes: 1

Views: 781

Answers (1)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230551

Here's a trick involving self.extended hook and eigenclasses.

class User
  def self.haz_many name
    define_method name do 
      "value of #{name}"
    end
  end
end

module Seller
  def self.extended base
    base.singleton_class.instance_eval do
      haz_many :sellers
    end
  end
end

u1 = User.new
u1.extend Seller
u1.respond_to? :sellers # => true

u2 = User.new
u2.respond_to? :sellers # => false

Upvotes: 2

Related Questions