# Referencing a non-ActiveRecord attribute

**URL:** <https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404>\
**Category:** Rails\
**Created:** [February 16, 2009, 12:54am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404 "2009-02-16T00:54:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 16, 2009, 12:54am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/1 "2009-02-16T00:54:59Z")

</div>

I am trying to access a model’s attribute that does not have a column  
in the model’s corresponding table. It exists only through an  
attr\_accessor:

class Widget \< ActiveRecord::Base  
attr\_accessor :attribute\_not\_in\_db  
end

I can access the attribute directly:

> > w = Widget.new(:attribute\_not\_in\_db =\> “foo”)  
> > w.attribute\_not\_in\_db  
> > =\> “foo”

However, I can’t seem to access it other ways:

> > attr\_symbol = :attribute\_not\_in\_db  
> > w[attr\_symbol]  
> > =\> nil

> > attr\_name = “attribute\_not\_in\_db”  
> > w[attr\_name]  
> > =\> nil

> > w.read\_attribute(attr\_symbol)  
> > =\> nil

> > w.read\_attribute(attr\_name)  
> > =\> nil

This is probably rather basic, but my searching hasn’t turned up the  
answer. Any guidance would be apprecited.

thx.

---

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 16, 2009, 4:51am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/2 "2009-02-16T04:51:18Z")

</div>

One way to dynamically add attributes to some model object on the fly  
is to just directly add the new key(s)/val(s) to the model instance’s  
attributes:

$ ./script/console  
Loading development environment (Rails 2.2.2)

> > test = Test.find(:first)  
> > =\> #\<Test id: 1, name: “Abe”\>

> > test.attributes.keys  
> > =\> [“id”, “name”]

> > test[“favorite\_color”] = ‘blue’  
> > =\> “blue”

> > test.attributes.keys  
> > =\> [“id”, “favorite\_color”, “name”]

> > test.favorite\_color  
> > =\> “blue”

Another way, assuming the purpose is to add additional attribs coming  
from a db qry, … Note that any additional attribs returned from a  
db query will be automatically added to the returned model ob(s):

> > test2 = Test.find\_by\_sql(“select \*, ‘blue’ as favorite\_color from tests order by id limit 1”).first  
> > =\> #\<Test id: 1, name: “Abe”\>

> > test2.attributes.keys  
> > =\> [“id”, “favorite\_color”, “name”]

> > test2.favorite\_color  
> > =\> “blue”

Note that neither of the above requires any accessor-related code in  
your model ob (unless you want/need it for other purposes):

$ cat app/models/test.rb  
class Test \< ActiveRecord::Base  
end

Jeff

---

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 16, 2009, 6:16am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/3 "2009-02-16T06:16:04Z")

</div>

Okay, I found a solution. It isn’t very readable, but it works:

user = User.new(:login=\> “foo”, :password=\>“bar”) # :password is not  
a column in the db, but defined in the model using  
“attr\_accessor :password” (see initial post)  
[:login, :password].each do |x|  
getter = x # =\> :password  
setter = (x.to\_s \<\< “=”).to\_sym # =\> :password=  
original\_val = user.method(getter).call  
user.method(setter).call(some\_new\_val)  
do\_some\_test(user)  
user.method(setter).call(original\_val)  
end

Any clean up suggestion?

---

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 16, 2009, 6:44am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/4 "2009-02-16T06:44:43Z")

</div>

The reason to add extra attributes as shown in my example is to allow  
for the accessor goodies provided by ActiveRecord for the model ob:

$ cat app/models/hit.rb  
class Test \< ActiveRecord::Base  
attr\_accessor :foo  
end

$ ./script/console  
Loading development environment (Rails 2.2.2)

> > test = Test.new  
> > =\> #\<Test id: nil, name: nil\>

> > test.id = 987  
> > =\> 987

> > test[:id]  
> > =\> 987

> > test[“id”]  
> > =\> 987

> > test.foo = ‘bar’  
> > =\> “bar”

> > test[:foo]  
> > =\> nil #huh?

> > test[“foo”]  
> > =\> nil #huh?

> > test.attributes.keys  
> > =\> [“id”, “name”] #huh?

### add key/val via model ob’s attributes:

> > test[‘foo’] = ‘bar’  
> > =\> “bar” #cool.

> > test.foo  
> > =\> “bar” #cool.

> > test[:foo]  
> > =\> “bar” #cool.

> > test.attributes.keys  
> > =\> [“id”, “foo”, “name”] #cool.

So, for your User example, if you changed the adding of password  
attrib as:

…  
user[“password”] = “bar”  
…

then your orig code should work as you intended.

Hope that helps,

Jeff

---

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 17, 2009, 2:38am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/5 "2009-02-17T02:38:34Z")

</div>

On Feb 16, 12:14 am, rapdup [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> do_some_test(user)
> user.method(setter).call(original_val)
> 
> ```
> 
> end
> 
> Any clean up suggestion?

This is marginally cleaner IMO:

[:login, :password].each do |getter|  
setter = “#{getter}=”  
original\_val = user.send(getter)  
user.send(setter, some\_new\_val)  
do\_some\_test(user)  
user.send(setter, original\_val)  
end

---

<div class="post-metadata">

**Author:** ![rapdup](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/b5e925/32.png) [@rapdup](https://www.ruby-forum.com/u/rapdup)\
**Post date:** [February 16, 2009, 5:39am UTC](https://www.ruby-forum.com/t/referencing-a-non-activerecord-attribute/160404/6 "2009-02-16T05:39:50Z")

</div>

Thanks for the response.  
I’m afraid my initial post wasn’t clear as it could be. I am trying to  
find a specific syntax to access an accessor getter/setter using a  
variable, in this example “x”:

user = User.new(:login=\> “foo”, :password=\>“bar”) # :password is not  
a column in the db, but defined in the model using  
“attr\_accessor :password” (see initial post)

[:login, :password].each do |x|  
original\_val = user[x]  
user[x] = some\_new\_val  
do\_some\_test(user)  
user[x] = original\_val  
end

It works for :login which is an actual attribute of User. However,  
since :password was created as an attribute accessor (def password &  
def password=), the syntax “user[e]” doesn’t work. I’m looking for a  
way to make this work while keeping “attr\_accessor :password”

I hope this is clearer.  
Thanks for the assist.
