# Accessing a class's variables from an included module

**URL:** <https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790>\
**Category:** Rails\
**Created:** [June 7, 2010, 9:42pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790 "2010-06-07T21:42:46Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 7, 2010, 9:42pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/1 "2010-06-07T21:42:46Z")

</div>

I created a mixin module called BaseProduct. This module has an  
initialize method in it. I am trying to use some meta-programming to  
set variables in initialize from the class that the module is in  
included in… I pass a CSV row into the initialize method and it needs  
to set all the variables. Its a bit confusing trying to explain it, but  
here is what it looks like:

## Note: the real world scenario is a bit more complicated using different objects, but I simplified it here to use a “product” scenario.

#\<table\_fields\_from\_class\> is pseudo-code

Module BaseProduct  
def self.included(base)  
#some stuff goes here  
end

def initialize(attributes = nil,row)  
super(attributes)  
\<table\_fields\_from\_class\>.each\_with\_index do |field,i|  
#NOTE: row is an array of values (csv row to array)  
eval(“self.#{field} = row[#{i}]”)  
end  
end  
end

class ShirtProduct \< ActiveRecord::Base  
\<table\_fields\_from\_class\> = [“size”,“color”,“collar\_type”]  
include BaseProduct  
end

class PantsProduct \< ActiveRecord::Base  
\<table\_fields\_from\_class\> = [“waist”,“length”,“material”]  
include BaseProduct  
end

* * *

I am import data from different CSVs (one for each type of product…  
each having different attributes) into tables by so using this code I  
want to be able to do this in rails:

pants = PantsProduct.new(nil,csv\_row)  
pants.save

I dont want to have to code an initialize method for every type of  
product and I thought it would be much easier to use metaprogramming and  
just pass an array of fields to a base initialize method. I may be way  
off here and there may be a completely different design pattern that  
would support this use case better, but this is what I originally came  
up with. I have tried several things with attr\_accessor, CONSTANTS,  
etc… but I have not been able to get the initialize method to see  
variables I set in the class. I am probably missing something simple as  
I don’t fully understand the module’s scope of access to the class…  
seems pretty straight forward vice-versa (class from module), but the  
other way around is confusing me a bit. let me know if you got any  
ideas. THANKS!

---

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 7, 2010, 9:51pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/2 "2010-06-07T21:51:52Z")

</div>

On 7 June 2010 20:42, Yanni M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I created a mixin module called BaseProduct. This module has an  
> initialize method in it. I am trying to use some meta-programming to  
> set variables in initialize from the class that the module is in  
> included in…

There’s a lot of recommendation against overloading initialize for  
AR::Base classes:  
[http://www.google.co.uk/search?sourceid=chrome&ie=UTF-8&q=rails+overload+initialize](http://www.google.co.uk/search?sourceid=chrome&ie=UTF-8&q=rails+overload+initialize)

Regardless, I think you’re “solving” your problem the wrong way -  
you’re _never_ going to be able to instanciate an object without a CSV  
row; is that really what you want? How will the rest of your  
application work when you just want to query the DB for  
ShirtProduct.first?

---

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 7, 2010, 9:57pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/3 "2010-06-07T21:57:09Z")

</div>

On 7 June 2010 20:42, Yanni M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> class ShirtProduct \< ActiveRecord::Base  
> end
> 
> class PantsProduct \< ActiveRecord::Base  
> end

And have you _really_ designed to have a different table for different  
types of product? I can only imagine lots of pain that will be caused  
by that further down the line.

I’d suggest a look at polymorphism.

---

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 7, 2010, 10:00pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/4 "2010-06-07T22:00:39Z")

</div>

On 7 Jun 2010, at 20:42, Yanni M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 

Don’t use eval for this - send(“#{field}=”, value) will do the trick

> other way around is confusing me a bit. let me know if you got any  
> ideas. THANKS!

If you choose to go down the constant route, remember that constants are  
scoped lexically. Try something like self.class::SOME\_CONSTANT

Michael’s advice is also sensible - writing a create\_from\_csv\_row method  
is probably sounder

Fred

---

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 7, 2010, 10:29pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/5 "2010-06-07T22:29:47Z")

</div>

Thanks guys for the quick responses… looks like I will go back to the  
drawing board. I was trying to force it in the initialize method to  
save a line of code, but creating create\_from\_csv\_row is a much better  
solution giving the problems you guys outlined here. Looks like  
polymorphism may solve some of my problems if I can rework my legacy db  
schema a bit.

> Regardless, I think you’re “solving” your problem the wrong way -  
> you’re _never_ going to be able to instanciate an object without a CSV  
> row; is that really what you want? How will the rest of your  
> application work when you just want to query the DB for  
> ShirtProduct.first?

I actually included a check which I left out of the simplified code,  
which will allow regular use of initialize method if I leave out the  
row:

def initialize(attributes = nil,row=nil)  
super(attributes)  
unless row.blank?  
#ugly code goes here  
end  
end

I was messing around with this some more and I figured out I can use  
class variables to achieve what I was trying to do. Set the class var  
in first line of the module: @@table\_fields and then reset it in the  
class. The module has access to it in the class var in the initialize  
method after this. Although I am scrapping this design in favor of what  
was suggested… figured I would still post what I came up with.

---

<div class="post-metadata">

**Author:** ![yannimac](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/7993a0/32.png) [@yannimac](https://www.ruby-forum.com/u/yannimac)\
**Post date:** [June 8, 2010, 3:44pm UTC](https://www.ruby-forum.com/t/accessing-a-classs-variables-from-an-included-module/189790/6 "2010-06-08T15:44:23Z")

</div>

Michael P. wrote:

> On 7 June 2010 20:42, Yanni M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > class ShirtProduct \< ActiveRecord::Base  
> > end
> > 
> > class PantsProduct \< ActiveRecord::Base  
> > end
> 
> And have you _really_ designed to have a different table for different  
> types of product? I can only imagine lots of pain that will be caused  
> by that further down the line.
> 
> I’d suggest a look at polymorphism.

My original example is polymorphism using mixin modules/duck typing.  
Are you referring to STI? I read a while back that STI was a bad choice  
unless your fields are almost the same for every subclass. I am using  
sort of a hybrid form of STI as you can see in my current design below.  
Can you explain which implementation of polymorphism you were referring  
to? In my use case the fields can vary a good bit from type to type,  
and the types share about 20% of the fields with the parent class. I am  
more concerned about sharing methods than I am fields in these  
associations, but I do need to use a parent table to retrieve all  
records from every subclass, so I don’t have to do a bunch of crazy  
joins. My real use case is as follows. If you have 5 minutes to read  
my lengthy use case, can you explain which design you would choose and  
why?

USE CASE:  
I am rewriting some software I use to track affiliate network  
transactions and I am going to release it open source, so I want to make  
sure the design is sound. The original software was basically a quick  
hack written in a day to get some info in my tables. But as I expand my  
use of these tables I realize the limitations and I need something that  
is designed well and maintainable.

An affiliate network = website that tracks clicks from a publisher  
website over to a merchant website and records if a purchase is made.  
The affiliate network then records transactions from the merchant  
website and makes them available to the publisher so they can see how  
much commission they earned from each sale. There are 8 major affiliate  
networks that I pull transactions from right now and in the next 5  
years, maybe that will grow to 20 or 30… and maybe up to 100 if  
someone adds smaller networks to my open source branch.

In the most basic form a transaction (which will be a single  
instance/database row of the class) includes a date, a sale amount, and  
a commission amount. Each network has a different way of representing  
this data and they all include additional fields that are different.

I want to preserve the integrity of the original data from each network  
in my database in case I need it later on… otherwise I would just  
manipulate the data when I pull it and insert it into one table with the  
common fields (date,sale,commission,network) and drop the rest of the  
data. I also need to get the transactions in various formats (csv,xml)  
from various sources using REST & SOAP, so each subclass (affiliate  
network) will have some custom functionality in grabbing the data. For  
these 2 reasons, I was planning on having a separate model and table for  
each subclass.

So here is my current design. I created a mixin module called  
BaseTransaction for all the shared functionality. Then I have a class  
called GeneralTransaction that is an activerecord model. I have a  
seperate transaction subclass for each affiliate network…  
AffiliateOneTransaction, etc. Each subclass uses the BaseTransaction  
mixin module for shared functionality. I am trying to remember, but I  
think I chose the mixin module method because I could not use Ruby  
inheritence “\<” with activerecord and have a seperate table for each  
subclass. A GeneralTransaction is inserted every time a subclass record  
is inserted and GeneralTransaction has subclass & subclass\_id fields to  
reference the records in the subclass table. Seems a little bit hairy  
to do it this way, but it will work. I am just trying to figure out if  
there is a more “correct” way to do this design. Any thoughts and  
suggestions are much appreciated. Thanks if you took the time to read  
my lengthy post!
