Bo Yi
Bo Yi

Reputation: 143

How can I open a class and convert it into ActiveRecord object? (for example, make it inherit ActiveRecord::Base)

I have a class called Journey that contains a lot of class methods. Now that I've got a table "journeys" i'd like to have a corresponding Journey ActiveRecord class too. Obviously all I have to do is add "< ActiveRecord::Base" in the class but I am wondering if it is possible to modify Journey class in Rails console so it becomes an ActiveRecord class without touching the source code?

I googled how to changed the parent class dynamically for a class and seems that it's impossible?.. Is there any other way then? Like, creating new class with the same name that will contain everything from old Journey but also inherit ActiveRecord::Base? Or maybe there is some other way to convert a class into ActiveRecord class?

It's not something I really need (as i can just modify the source code of the project in real life), but i am really curious if it's theoretically possible to do in Ruby -- I am just used to the fact that almost everything in Ruby can be done on the fly, I wonder if this is doable too?..

  class Journey
    def self.find_for(vehicle, start_date, end_date)
      # ...
    end

    # ... lots of other class methods
  end

Upvotes: 2

Views: 194

Answers (3)

fylooi
fylooi

Reputation: 3870

Sounds like what you want is access to the class methods from your original Journey class. You can't combine two classes, but you can proxy calls to the original class, eg (totally untested).

class NewJourney < ActiveRecord::Base
  self.table_name = "journeys"

  class << self
    def method_missing?(method, *args, &block)
      Journey.send(method, *args, &block)
    end
  end
end

Upvotes: 1

J&#246;rg W Mittag
J&#246;rg W Mittag

Reputation: 369584

You cannot change the superclass of a class. (Well, technically, Module#include calls Module#append_features, which in most implementations creates an include class and makes that class the superclass of the class that include is called on, but you cannot do that in user code.)

You will have to either change your original class definition or create a new class. There is no way around that.

Upvotes: 1

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230521

Not sure about modifying an existing class, but you can define a new one and point the name to it. Something like this:

Journey = Class.new(ActiveRecord::Base) do
  # class body
end

Upvotes: 3

Related Questions