# Defining an ActiveRecord class within a method of another class

**URL:** <https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823>\
**Category:** Ruby\
**Created:** [January 28, 2009, 3:06pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823 "2009-01-28T15:06:20Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [January 28, 2009, 3:06pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823/1 "2009-01-28T15:06:20Z")

</div>

Hi,

I want to create a class and define a subclass of ActiveRecord within  
that class, like this:

class Results  
def initialize(db)  
class db \< ActiveRecord::Base  
end  
end  
end

r1 = Results.new(‘DM’)  
r2 = Results.new(‘AE’)

Then I want to put that class definition into an object and use it in  
the instance methods of the Results class. (The instance methods of the  
Results class will do stuff with database tables, but I want to pick  
which table when I create the instances of the Results class.)

I am sure that the syntax above is wrong – probably in many ways – but  
am unsure how to fix it. Ruby does not seem to want to allow class  
definitions within methods, but if I can’t do that, I do not know of  
another way to do this.

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [January 28, 2009, 3:27pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823/2 "2009-01-28T15:27:07Z")

</div>

I’m guessing this would do the trick :

irb(main):042:0\> class Res  
irb(main):043:1\> def self.get(cls)  
irb(main):044:2\> eval(“class #{cls};end”)  
irb(main):045:2\> return eval("#{cls}.new")  
irb(main):046:2\> end  
irb(main):047:1\> end  
irb(main):042:0\> class Res  
irb(main):043:1\> def self.get(cls)  
irb(main):044:2\> eval(“class #{cls};end”)  
irb(main):045:2\> return eval("#{cls}.new")  
irb(main):046:2\> end  
irb(main):047:1\> end

You can modify what’s being evaled .

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [January 28, 2009, 3:28pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823/3 "2009-01-28T15:28:14Z")

</div>

Sorry , I pasted the same thing twice

irb(main):042:0\> class Res  
irb(main):043:1\> def self.get(cls)  
irb(main):044:2\> eval(“class #{cls};end”)  
irb(main):045:2\> return eval("#{cls}.new")  
irb(main):046:2\> end  
irb(main):047:1\> end  
=\> nil  
irb(main):048:0\> x = Res.get(“G”)  
=\> #Res::G:0xb7c05d5c  
irb(main):049:0\> x.class  
=\> Res::G

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [January 28, 2009, 4:53pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823/4 "2009-01-28T16:53:56Z")

</div>

On Wed, Jan 28, 2009 at 2:22 PM, Glenn [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> r1 = Results.new(‘DM’)  
> r2 = Results.new(‘AE’)
> 
> Then I want to put that class definition into an object and use it in the instance methods of the Results class. (The instance methods of the Results class will do stuff with database tables, but I want to pick which table when I create the instances of the Results class.)
> 
> I am sure that the syntax above is wrong – probably in many ways – but am unsure how to fix it. Ruby does not seem to want to allow class definitions within methods, but if I can’t do that, I do not know of another way to do this.

Maybe this helps: I created a table named A, with id and description.  
Then (you have require active\_record and establish the connection):

irb(main):081:0\> class Result  
irb(main):082:1\> def initialize table  
irb(main):083:2\> @db = Class.new(ActiveRecord::Base) do  
irb(main):084:3\* set\_table\_name table  
irb(main):085:3\> end  
irb(main):086:2\> end  
irb(main):087:1\> attr\_reader :db  
irb(main):088:1\> end  
=\> nil  
irb(main):089:0\> a = Result.new(“A”)  
=\> #\<Result:0xb7478bc0 @db=#Class:0xb7478b98(id: integer,  
description: string)\>  
irb(main):090:0\> a.db.find(:all)  
=\> [#\<#Class:0xb7478b98 id: 1, description: “test”\>,  
#\<#Class:0xb7478b98 id: 2, description: “test 2”\>]

I did the set\_table\_name because I think you want to choose the table  
name to be the parameter passed to the Result initialize method, and  
skip ActiveRecord’s pluralization stuff. I store the generated class  
in an instance variable. Through this variable you get access to the  
ActiveRecord class.

Jesus.

---

<div class="post-metadata">

**Author:** ![glenn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/4bbf92/32.png) [@glenn](https://www.ruby-forum.com/u/glenn)\
**Post date:** [January 28, 2009, 8:09pm UTC](https://www.ruby-forum.com/t/defining-an-activerecord-class-within-a-method-of-another-class/158823/5 "2009-01-28T20:09:23Z")

</div>

Glenn wrote:

> Hi,
> 
> I want to create a class and define a subclass of ActiveRecord within  
> that class, like this:
> 
> class Results  
> def initialize(db)  
> class db \< ActiveRecord::Base  
> end  
> end  
> end
> 
> r1 = Results.new(‘DM’)  
> r2 = Results.new(‘AE’)

Class.new(superclass) should do what you need without need to eval  
anything. This gives you an anonymous class, which you can then assign  
to a constant to give it a proper class name. Something like (untested):

class Results  
def initialize(name)  
@klass = Results.const\_set(name, Class.new(ActiveRecord::Base))  
end  
def query  
@klass.find(…)  
end  
end

r1 = Results.new(‘DM’)  
Results::DM.find(…)
