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. -- Posted via http://www.ruby-forum.com/.
On Fri, Jan 30, 2009 at 3:45 PM, James Byrne <lists at ruby-forum.com> wrote:> 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.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 Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com
James Byrne wrote:> This is a request for a programming technique:Got it... t1.read_attribute(column) -- Posted via http://www.ruby-forum.com/.
Zach Dennis 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. -- Posted via http://www.ruby-forum.com/.
On Fri, Jan 30, 2009 at 3:56 PM, James Byrne <lists at ruby-forum.com> wrote:> Zach Dennis 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. > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > 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
Pat Maddox wrote:> I realize you didn''t ask for all of that but I''m feeling a bit chatty. > > PatThe 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: [](attr_name) 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[](attr_name)" 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 []. -- Posted via http://www.ruby-forum.com/.
On Sat, Jan 31, 2009 at 6:18 AM, James Byrne <lists at ruby-forum.com> wrote:> Pat Maddox 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: > > [](attr_name) > > 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]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 [](element) .... 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 [](attr_name). 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