# Referencing a non-ActiveRecord attribute

**URL:** <https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395>\
**Category:** rubyonrails-talk\
**Created:** [February 15, 2009, 11:54pm UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395 "2009-02-15T23:54:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rapdup](https://avatars.discourse-cdn.com/v4/letter/r/b5e925/32.png) [@rapdup](https://discuss.rubyonrails.org/u/rapdup)\
**Post date:** [February 15, 2009, 11:54pm UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/1 "2009-02-15T23:54:33Z")

</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 &nbsp;&nbsp;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:** ![Jeff\_Burly](https://avatars.discourse-cdn.com/v4/letter/j/c68b51/32.png) [@Jeff\_Burly](https://discuss.rubyonrails.org/u/Jeff_Burly)\
**Post date:** [February 16, 2009, 3:50am UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/2 "2009-02-16T03:50:41Z")

</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://avatars.discourse-cdn.com/v4/letter/r/b5e925/32.png) [@rapdup](https://discuss.rubyonrails.org/u/rapdup)\
**Post date:** [February 16, 2009, 4:39am UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/3 "2009-02-16T04:39:15Z")

</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| &nbsp;&nbsp;&nbsp;&nbsp;original\_val = user &nbsp;&nbsp;&nbsp;&nbsp;user = some\_new\_val &nbsp;&nbsp;&nbsp;&nbsp;do\_some\_test(user) &nbsp;&nbsp;&nbsp;&nbsp;user = 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.

---

<div class="post-metadata">

**Author:** ![rapdup](https://avatars.discourse-cdn.com/v4/letter/r/b5e925/32.png) [@rapdup](https://discuss.rubyonrails.org/u/rapdup)\
**Post date:** [February 16, 2009, 5:14am UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/4 "2009-02-16T05:14:34Z")

</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| &nbsp;&nbsp;&nbsp;&nbsp;getter = x # =\> :password &nbsp;&nbsp;&nbsp;&nbsp;setter = (x.to\_s \<\< "=").to\_sym # =\> :password= &nbsp;&nbsp;&nbsp;&nbsp;original\_val = user.method(getter).call &nbsp;&nbsp;&nbsp;&nbsp;user.method(setter).call(some\_new\_val) &nbsp;&nbsp;&nbsp;&nbsp;do\_some\_test(user) &nbsp;&nbsp;&nbsp;&nbsp;user.method(setter).call(original\_val) end

Any clean up suggestion?

---

<div class="post-metadata">

**Author:** ![Jeff\_Burly](https://avatars.discourse-cdn.com/v4/letter/j/c68b51/32.png) [@Jeff\_Burly](https://discuss.rubyonrails.org/u/Jeff_Burly)\
**Post date:** [February 16, 2009, 5:43am UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/5 "2009-02-16T05:43:54Z")

</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 &nbsp;&nbsp;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:** ![jeff\_emminger](https://avatars.discourse-cdn.com/v4/letter/j/aca169/32.png) [@jeff\_emminger](https://discuss.rubyonrails.org/u/jeff_emminger)\
**Post date:** [February 17, 2009, 1:37am UTC](https://discuss.rubyonrails.org/t/referencing-a-non-activerecord-attribute/39395/6 "2009-02-17T01:37:54Z")

</div>

This is marginally cleaner IMO:

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