Hi. A couple of days ago I posted a question about how to simplify the task of converting string values to uppercase when saving a row and with some help I got to the point of writing the following in a before_save method to test the value''s contents: self.attributes.each_pair do |k,v| puts "Column #{k}: regular value = #{v} - upcase value #{v.upcase!}" if v.class.name == ''String'' end The problem I am having is that I can use upcase! all I want against ''v'' in this case but that will not change the column value, which is what I need to do. I have tried to use self.attribute_for_name(k).upcase! and some other things but I either got syntax errors (method not found, etc.) or what I tried did not work. I am relatively new to RoR and any help would be greatly appreciated. Thanks. Pepe --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Have you tried explicitly setting v = v.upcase in your before_save callback? On Jul 11, 1:50 pm, pepe <P...-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote:> Hi. > > A couple of days ago I posted a question about how to simplify the > task of converting string values to uppercase when saving a row and > with some help I got to the point of writing the following in a > before_save method to test the value''s contents: > > self.attributes.each_pair do |k,v| > puts "Column #{k}: regular value = #{v} - upcase value > #{v.upcase!}" if v.class.name == ''String'' > end > > The problem I am having is that I can use upcase! all I want against > ''v'' in this case but that will not change the column value, which is > what I need to do. I have tried to use > self.attribute_for_name(k).upcase! and some other things but I either > got syntax errors (method not found, etc.) or what I tried did not > work. I am relatively new to RoR and any help would be greatly > appreciated. > > Thanks. > > Pepe--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
pepe wrote:> self.attributes.each_pair do |k,v| > puts "Column #{k}: regular value = #{v} - upcase value > #{v.upcase!}" if v.class.name == ''String'' > end >Right. In this case, v is just a local variable of sorts, so it''s not going to change the object. You need to do something along the lines of self.send(k).upcase! if self.send(k).class == String I just did a quick test in console, and that worked. There might be a better way to do it, though. Peace, Phillip -- 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 -~----------~----~----~----~------~----~------~--~---
before_save :upcase_attributes private # Upcase any attributes that are strings def upcase_attributes self.attributes.each_pair do |key, value| self[key] = value.upcase if self[key].is_a? String end end That''s probably the most appropriate way to do it. Instead of using the methods, I just access the attributes themselves which can be faster. Also note that I''m not overriding before_save directly, but rather using a method call. This way I can do multiple things before saving. --~--~---------~--~----~------------~-------~--~----~ 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 -- On Fri, 11 Jul 2008, Brian Hogan wrote:> Also note that I''m not overriding before_save directly, but rather using a > method call. This way I can do multiple things before saving.You can actually mix and match. If you do this: class MyModel < ARB def before_save puts "Instance method" end before_save :do_something before_save { puts "block given to before_save" } before_save { puts "another block given to before_save" } def do_something puts "Method referenced by before_save" end end then when you save, you''ll get this: Method referenced by before_save block given to before_save another block given to before_save Instance method David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails July 21-24 Edison, NJ Advancing With Rails August 18-21 Edison, NJ See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ 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 -- On Fri, 11 Jul 2008, Reid Lynch wrote:> On Jul 11, 1:50pm, pepe <P...-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote: >> Hi. >> >> A couple of days ago I posted a question about how to simplify the >> task of converting string values to uppercase when saving a row and >> with some help I got to the point of writing the following in a >> before_save method to test the value''s contents: >> >> self.attributes.each_pair do |k,v| >> puts "Column #{k}: regular value = #{v} - upcase value >> #{v.upcase!}" if v.class.name == ''String'' >> end >> >> The problem I am having is that I can use upcase! all I want against >> ''v'' in this case but that will not change the column value, which is >> what I need to do. I have tried to use >> self.attribute_for_name(k).upcase! and some other things but I either >> got syntax errors (method not found, etc.) or what I tried did not >> work. I am relatively new to RoR and any help would be greatly >> appreciated. >> > > Have you tried explicitly setting v = v.upcase in your before_save > callback?That won''t work. It just attaches the identifier ''v'' to a new object. h = { "one" => 1 } h.each {|k,v| v = "ONE" } p h # => { "one" => 1 } You have to assign to the hash via its keys. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails July 21-24 Edison, NJ Advancing With Rails August 18-21 Edison, NJ See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On 11 Jul 2008, at 22:27, David A. Black wrote:>> >> Have you tried explicitly setting v = v.upcase in your before_save >> callback? > > That won''t work. It just attaches the identifier ''v'' to a new object. > > h = { "one" => 1 } > h.each {|k,v| v = "ONE" } > p h # => { "one" => 1 } > > You have to assign to the hash via its keys. >Although prior to rails 2.1 fiddling with the attributes hash is a waste of time because it always used to return you a fresh (and deep) copy of the attributes. This changed in rails 2.1 Fred --~--~---------~--~----~------------~-------~--~----~ 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 -- On Fri, 11 Jul 2008, Frederick Cheung wrote:> > > On 11 Jul 2008, at 22:27, David A. Black wrote: >>> >>> Have you tried explicitly setting v = v.upcase in your before_save >>> callback? >> >> That won''t work. It just attaches the identifier ''v'' to a new object. >> >> h = { "one" => 1 } >> h.each {|k,v| v = "ONE" } >> p h # => { "one" => 1 } >> >> You have to assign to the hash via its keys. >> > > Although prior to rails 2.1 fiddling with the attributes hash is a > waste of time because it always used to return you a fresh (and deep) > copy of the attributes. This changed in rails 2.1I had lapsed into focusing on the assignment semantics per se, but indeed if it''s a copy anyway, it won''t do any good even if one does assign to it. It doesn''t look like it changed in 2.1.0: def attributes self.attribute_names.inject({}) do |attrs, name| attrs[name] = read_attribute(name) attrs end end Is there another way in that you''re thinking of, or maybe it''s on edge? David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails July 21-24 Edison, NJ Advancing With Rails August 18-21 Edison, NJ See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
On 11 Jul 2008, at 23:42, David A. Black wrote:> > Hi -- > > I had lapsed into focusing on the assignment semantics per se, but > indeed if it''s a copy anyway, it won''t do any good even if one does > assign to it. It doesn''t look like it changed in 2.1.0: > > def attributes > self.attribute_names.inject({}) do |attrs, name| > attrs[name] = read_attribute(name) > attrs > end > endIsn''t that ok though (in this particular case), since that''s basically def attributes self.attribute_names.inject({}) do |attrs, name| attrs[name] = @attributes[name] attrs end end ie self.attributes does have as values the same objects that @attributes has as values. We can''t changed attributes by assigning to self.attributes, but in place (eg upcase!) modification of self.attributes should work. On the other hand, before 2.1 it was basically attrs[name] = @attributes[name].clone in which case you''ve haven''t got a snowballs chance in hell of changing an attribute by acting on self.attributes. I think this demonstrates that trying to modify attributes by acting on self.attributes is not a good idea :-) Fred --~--~---------~--~----~------------~-------~--~----~ 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 -- On Sat, 12 Jul 2008, Frederick Cheung wrote:> > > On 11 Jul 2008, at 23:42, David A. Black wrote: > >> >> Hi -- >> >> I had lapsed into focusing on the assignment semantics per se, but >> indeed if it''s a copy anyway, it won''t do any good even if one does >> assign to it. It doesn''t look like it changed in 2.1.0: >> >> def attributes >> self.attribute_names.inject({}) do |attrs, name| >> attrs[name] = read_attribute(name) >> attrs >> end >> end > > Isn''t that ok though (in this particular case), since that''s basically > def attributes > self.attribute_names.inject({}) do |attrs, name| > attrs[name] = @attributes[name] > attrs > end > end > > ie self.attributes does have as values the same objects that > @attributes has as values. We can''t changed attributes by assigning to > self.attributes, but in place (eg upcase!) modification of > self.attributes should work.OK, I see what you mean. I was thinking you meant that assigning to keys would work (e.g., obj.attributes["name"] = "David").> On the other hand, before 2.1 it was basically > > attrs[name] = @attributes[name].clone > > in which case you''ve haven''t got a snowballs chance in hell of > changing an attribute by acting on self.attributes. > > I think this demonstrates that trying to modify attributes by acting > on self.attributes is not a good idea :-)I agree. Of course there''s #attributes=, which thickens the plot a bit. David -- Rails training from David A. Black and Ruby Power and Light: Intro to Ruby on Rails July 21-24 Edison, NJ Advancing With Rails August 18-21 Edison, NJ See http://www.rubypal.com for details and updates! --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Hey, that''s nifty. I love this community :) On Fri, Jul 11, 2008 at 4:25 PM, David A. Black <dblack-0o/XNnkTkwhBDgjK7y7TUQ@public.gmane.org> wrote:> > Hi -- > > On Fri, 11 Jul 2008, Brian Hogan wrote: > > > Also note that I''m not overriding before_save directly, but rather using > a > > method call. This way I can do multiple things before saving. > > You can actually mix and match. If you do this: > > class MyModel < ARB > > def before_save > puts "Instance method" > end > > before_save :do_something > before_save { puts "block given to before_save" } > before_save { puts "another block given to before_save" } > def do_something > puts "Method referenced by before_save" > end > end > > then when you save, you''ll get this: > > Method referenced by before_save > block given to before_save > another block given to before_save > Instance method > > > David > > -- > Rails training from David A. Black and Ruby Power and Light: > Intro to Ruby on Rails July 21-24 Edison, NJ > Advancing With Rails August 18-21 Edison, NJ > See http://www.rubypal.com for details and updates! > > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
First of all I would like to thank everybody for their help. I have learned quite a few things by reading all the postings. However I got a little lost after Frederick Cheung''s posting and if you guys have time I''d appreciate a comment on the following: 1. What is a ''deep'' copy of an attribute? 2. What is @attributes? Based on what I know, could it be an instance variable of the model with attributes information? 3. And finally, what is #attributes=? It''s the first time I see something like that. And now to the code: I first tried Phillip Koebe''s code but for some reason it wouldn''t work but when I tried Brian Hogan''s it surely did the trick. Thanks a lot Brian! Reid, yes I tried to directly upcase the value but that wouldn''t work. I tried pretty much everything I could think of with my limited knowledge of RoR. Again, thanks a lot for all the help and comments. Pepe On Jul 11, 4:07 pm, "Brian Hogan" <bpho...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> before_save :upcase_attributes > > private > > # Upcase any attributes that are strings > def upcase_attributes > self.attributes.each_pair do |key, value| > self[key] = value.upcase if self[key].is_a? String > end > end > > That''s probably the most appropriate way to do it. Instead of using the > methods, I just access the attributes themselves which can be faster. > > Also note that I''m not overriding before_save directly, but rather using a > method call. This way I can do multiple things before saving.--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Jul 13, 2:38 pm, pepe <P...-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote:> First of all I would like to thank everybody for their help. I have > learned quite a few things by reading all the postings. However I got > a little lost after Frederick Cheung''s posting and if you guys have > time I''d appreciate a comment on the following: > > 1. What is a ''deep'' copy of an attribute?Say you have an array and you make a copy of it. That can be two things: - a new array (but which contains the same objects as the old one): a shallow copy - a new array, which contains copies of the contents of the old array: ( a deep copy)> 2. What is @attributes? Based on what I know, could it be an instance > variable of the model with attributes information?It''s where the attributes are actually stored. I would consider this an implementation detail> 3. And finally, what is #attributes=? It''s the first time I see > something like that. >The leading hash is a notation for instance methods. It means ''the method that is called when you do someobject.attributes = foo'' Fred --~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks a lot for the explanations, Fred. I appreciate it. :) Pepe On Jul 13, 1:40 pm, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Jul 13, 2:38 pm, pepe <P...-gUAqH5+0sKL6V6G2DxALlg@public.gmane.org> wrote:> First of all I would like to thank everybody for their help. I have > > learned quite a few things by reading all the postings. However I got > > a little lost after Frederick Cheung''s posting and if you guys have > > time I''d appreciate a comment on the following: > > > 1. What is a ''deep'' copy of an attribute? > > Say you have an array and you make a copy of it. That can be two > things: > - a new array (but which contains the same objects as the old one): a > shallow copy > - a new array, which contains copies of the contents of the old array: > ( a deep copy) > > > 2. What is @attributes? Based on what I know, could it be an instance > > variable of the model with attributes information? > > It''s where the attributes are actually stored. I would consider this > an implementation detail > > > 3. And finally, what is #attributes=? It''s the first time I see > > something like that. > > The leading hash is a notation for instance methods. It means ''the > method that is called when you do someobject.attributes = foo'' > > Fred--~--~---------~--~----~------------~-------~--~----~ 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@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---