Hi Everyone, I have a requirement where the method name of an Object will be generated and accessed dynamically in code. When I tried to access it showed me "undefined method". Am attaching a sample code of what i want to accomplish: @user_information = UserInformation.new @table_fields = UserInformation.find_by_sql("DESC user_informations") for table_field in @table_fields temp = table_field.Field # considering Field is `user_name` @user_information.temp = "vasanth" # referring to @user_information.user_name = "vasanth" end In the above example i will get an error like "undefined method `temp`" Can anyone tell me how to do this in Ruby on Rails? (I need something equivalent to "eval()" function present in Java Script) Thanks in Advance. Regards, VASANTH -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Guo Yangguang-2 wrote:> > > Hi Everyone, > I have a requirement where the method name of an Object will be > generated and accessed dynamically in code. When I tried to access it > showed me "undefined method". Am attaching a sample code of what i want > to accomplish: > > @user_information = UserInformation.new > @table_fields = UserInformation.find_by_sql("DESC user_informations") > for table_field in @table_fields > temp = table_field.Field # considering Field is `user_name` > @user_information.temp = "vasanth" > # referring to @user_information.user_name = "vasanth" > end > > In the above example i will get an error like "undefined method `temp`" > > Can anyone tell me how to do this in Ruby on Rails? (I need something > equivalent to "eval()" function present in Java Script) >instance_variable_set is one method you should investigate for doing dynamic setters. You can find it sort of undocumented here: http://www.ruby-doc.org/core/classes/Object.src/M000381.html. But seriously, Google turns up lots on this topic. Your code would then read: for table_field in @table_fields @user_information.instance_variable_set("@#{table_field}", "vasanth") # referring to @user_information.send("@#{table_field}") # => "vasanth" end -- View this message in context: http://www.nabble.com/Dynamic-method-access-from-an-Object-tp15844292p15844465.html Sent from the RubyOnRails Users mailing list archive at Nabble.com. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Vasanthakumar Csk wrote:> I have a requirement where the method name of an Object will be > generated and accessed dynamically in code. When I tried to access it > showed me "undefined method". Am attaching a sample code of what i want > to accomplish:As well as Steve''s suggestion for this case, there is a general method available in Ruby for sending messages to invoke methods where the method name is in a string. The method #send does this: http://www.ruby-doc.org/core/classes/Object.html#M000334 However:> @user_information = UserInformation.new > @table_fields = UserInformation.find_by_sql("DESC user_informations")Try to avoid embedding SQL in your code if possible. You''ll make it more readable and more portable (especially if you decide to change your database at some point). The above will return an array of column properties which is not what you''re after anyway. To get the column names for a model, use: @table_fields = UserInformation.column_names> for table_field in @table_fields > temp = table_field.Field # considering Field is `user_name` > @user_information.temp = "vasanth" > # referring to @user_information.user_name = "vasanth" > endIf you are using a standard Rails model, then one of your columns will be called "id" and the above will try to overwrite this (numerical) value with a string. Not a good idea. This code is also very model oriented but gives the impression you are wanting to put this into a controller. Whenever you find yourself doing model logic like this, re-think your strategy. This sort of stuff should be in the model. So, if you really want the model to be able to set all attributes (except "id"!) to a particular string, then in your model: def set_to_string new_string attributes.keys.each do | attr | self.send "#{attr}=", new_string end end This form means that any setters you''ve overridden for any reason will be used and using #attributes to get the names automatically excludes "id". This is, of course, dangerous. It assumes that all your attributes are string values (does the model have "created_at" and "updated_at"?) and that if you ever add columns, you''ll want them to get the same treatment. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks a lot Steve and Bush. All the informations that you gave was new and very useful to me. Here is a bit more explanation of what i am trying to do:> This code is also very model oriented but gives the impression you are > wanting to put this into a controller. Whenever you find yourself doing > model logic like this, re-think your strategy. This sort of stuff > should be in the model. So, if you really want the model to be able to > set all attributes (except "id"!) to a particular string, then in your > model:I understand that my code is model oriented, so its in model only. Anyway thanks again for your suggestion.> This is, of course, dangerous. It assumes that all your attributes are > string values (does the model have "created_at" and "updated_at"?) and > that if you ever add columns, you''ll want them to get the same > treatment.Sorry that i couldn''t explain you the real scenario or give the actual code for you to analyse. But the case is like this, I have a "table A" with columns a1,a2,a3,a4 & a5. Now, there will be a procedure (user action) which will change only one/two column(s) in that "table A" eg: a3. The need of this is to generate a report based on changed value. Also i should not over-write the original value of a3 in "table A". Instead, i want to modify that object dynamically at run-time for further calculations. However, i dont know which column that user is going to change (till run-time). So i have to write IF condition for all 5 columns of "table A". But this will get tedious because i have more than 20 tables with 40 columns each. Hope you understood my problem. As you said, the user wont/cant modify "id" or "created_at" or "updated_at" etc. Hope you can help me in minimizing the code further, if any methods available. Thanks in Advance. Regards, VASANTH -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Vasanthakumar Csk wrote:> Instead, i want to modify that object dynamically at run-time for > further calculations. However, i dont know which column that user is > going to change (till run-time).In your model: def set_values columns, values (0...columns.length).each do |i| self.send "#{columns[i]}=", values[i] end end Then call this on the object you want to change with two arrays, one the set of columns the user wants to change and the other with the values. If the values will always be the same, then this reduces to: def set_values columns, new_value columns.each do | attr | seld.send "#{attr}=", new_value end end You should be able to fit any of these to your particular situation. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Hi Mark, Thanks a lot for your help. Its working fine. Learnt few new things in ROR because of you, thanks once again for that. Regards, Vasanth -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---