RSpec get model attribute values by name

This is a request for a programming technique:

Given

class Mymodel < ActiveRecord::Base
end

my_instance = Mymodel.new

If I am given a string representation of an attribute “xxx” what is the
most elegant way of passing that string to my_instance to retrieve its
value? This is probably a common idiom, given what Rails does, but I
cannot seem to find its code in the rails gem at the moment.

So, if anyone knows hoe to do this off the cuff I would appreciate it.
An example of the intended use of this is

def table_compare(table1, table2, array_of_attributes) do |t1, t2,
aon|
tint = t1.column_names & t2.column_names
tfin = tint & aon
tfin.each do |column|
return false if t1.column <> t2.column
end
return tfin #could be nil
end

I want to convert the string value of the column variable into the
attribute name to obtain the value of that attribute.

James B. wrote:

This is a request for a programming technique:

Got it…

t1.read_attribute(column)

On Fri, Jan 30, 2009 at 3:45 PM, James B. [email protected]
wrote:

most elegant way of passing that string to my_instance to retrieve its
tfin.each do |column|
return false if t1.column <> t2.column
end
return tfin #could be nil
end

I want to convert the string value of the column variable into the
attribute name to obtain the value of that attribute.

I’m assuming you want to treat your model instance like a hash:

m = MyModel.new :name => “foo”
m[“name”] # => “foo”

http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=M001972&name=[]

On a different note, how about some better variable names?


Zach D.
http://www.continuousthinking.com

On Fri, Jan 30, 2009 at 3:56 PM, James B. [email protected]
wrote:

That code was for demonstration purposes for this question only.

Posted via http://www.ruby-forum.com/.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

a = “name”

As Zach pointed out, you can access AR instance attributes like a hash:
my_instance[a] = “foobar”
my_instance[a.to_sym] # => “foobar”

the reason you can use either a symbol or a string is because the hash
access is done with a HashWithIndifferentAccess.

A couple other things you can do…

my_instance.send(a) # => “foobar”

It’s important to view method calls as sending messages to objects in
Ruby… send is a method you can use to send a message to an object,
where the method name is known only at runtime.

eval “my_instance.#{a}”

and then of course you can eval strings…so if you have a var
containing the name, you can interpolate it into another string and
eval that.

I realize you didn’t ask for all of that but I’m feeling a bit chatty.

Pat

Zach D. wrote:

m = MyModel.new :name => “foo”
m[“name”] # => “foo”

http://www.railsbrain.com/api/rails-2.2.2/doc/index.html?a=M001972&name=[]

On a different note, how about some better variable names?

That code was for demonstration purposes for this question only.

Pat M. wrote:

I realize you didn’t ask for all of that but I’m feeling a bit chatty.

Pat

The more information the better. I never really did understand exactly
what using eval() was supposed to accomplish, now I do. Chat away…

I do want to point out that this is what the ActiveRecord::Base api has
to say about the [] method:

Returns the value of the attribute identified by attr_name after it has
been typecast (for example, “2004-12-12” in a data column is cast to a
date object, like Date.new(2004, 12, 12)). (Alias for the protected
read_attribute method).

Notice anything wrong about the api call description? Should not this
say:

[attr_name]

Returns the value of the attribute identified by attr_name…

The reason that I raised this question to begin with was because I could
not get “model_instance” to work. Which is what the api is
telling me to do the way that it is written. I came up with the
alternative, write_attribute(attr_name), by looking at the code for [].

On Sat, Jan 31, 2009 at 6:18 AM, James B. [email protected]
wrote:

to say about the [] method:

[attr_name]

Not quite…

You must be looking at the rdoc. RDoc looks at the method definition,
and then includes any comments above it. Method definitions in ruby
are of the form
method_name(param1, param2, *other_params, &block)

and [] is just a method call. You can define it on your own objects
with
def … end

Note that you can do
{:foo => “abc”, :bar => “123”}.send :[], :foo

I just looked at the RDoc, and yeah you’re right that it shows it of
the form . That’s because RDoc just sticks in the method
as it’s defined. You would need to know that this is a special case
in Ruby where you really call it like blah[:foo]

Pat