I have asked about this issue on several different mailing lists and have had no response. If anyone here can offer some advice then I would be much obliged. I have a feature that essentially says: Given I have a user "myuser" When I fill in "User Name" with "MyUser" And I press "Login" Then I should find a user "myuser" And I should be logged in The steps definitions for this are all quite conventional and at the moment "Then I should find the user "myuser"" is failing, as expected. My question is: What is best practice with respect to normalizing form input data? My feeling is that this sort of thing belongs in the model but I cannot see a way to get this to work. In short, how to implement this feature? I have extended String with a method called hll_keycase which preforms the desired normalization. The setter for Users.username is overridden in the model and the stored values in the database are all properly normalized. But, it seems to me at the moment that the only place to normalize form input data for the SELECT required to determine if the username exists or not is either in the form or in the controller. Is that the case? This has to be a recurring issue for data input forms and yet I can find very few resources on the web that address this issue at all, and those are often terse to the point of unintelligible. Not exactly a test issue but I really could use some guidance with this as whatever technique I finally adopt will pervade the entire project. -- Posted via http://www.ruby-forum.com/.
On Fri, Dec 19, 2008 at 7:50 AM, James Byrne <lists at ruby-forum.com> wrote:> I have asked about this issue on several different mailing lists and > have had no response. If anyone here can offer some advice then I would > be much obliged. > > I have a feature that essentially says: > > Given I have a user "myuser" > When I fill in "User Name" with "MyUser" > And I press "Login" > Then I should find a user "myuser" > And I should be logged in > > The steps definitions for this are all quite conventional and at the > moment "Then I should find the user "myuser"" is failing, as expected. > > My question is: What is best practice with respect to normalizing form > input data? My feeling is that this sort of thing belongs in the model > but I cannot see a way to get this to work. In short, how to implement > this feature? > > I have extended String with a method called hll_keycase which preforms > the desired normalization. The setter for Users.username is overridden > in the model and the stored values in the database are all properly > normalized. But, it seems to me at the moment that the only place to > normalize form input data for the SELECT required to determine if the > username exists or not is either in the form or in the controller. Is > that the case? > > This has to be a recurring issue for data input forms and yet I can find > very few resources on the web that address this issue at all, and those > are often terse to the point of unintelligible. > > Not exactly a test issue but I really could use some guidance with this > as whatever technique I finally adopt will pervade the entire project. > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >There are a couple things you can do. First, if you''re using webrat and you''ve labeled fields exactly as you have them in that feature, you can offload the work to webrat: When /^I fill in "(.*)" with "(.*)$/" do |field, value| fills_in field, :with => value end Or you can do some kind of transformation: prop_map = {"User name" => :username} When /^I fill in "(.*)" with "(.*)$/" do |prop_name, value| fills_in prop_map[prop_name], :with => value end or if you''re accessing the model directly @user.send(prop_map[prop_name] + ''='', value) Looking back at the full email now though I think you''re asking about how to just convert MyUser to myuser? class User < ActiveRecord::Base def username=(new_username) self[:username] = new_username.downcase end end or non-AR class User attr_reader :username def username=(new_username) @username = new_username.downcase end end Is that what you''re looking for? Pat
You can use read_attribute and write_attribute in models to do this sort of thing - though I''m not really clear exactly what it is you''re trying to do. I don''t think normalising is quite the right term here. Anyhow I think you''re saying that you have an attribute whose storage format is different from its presenation format. To deal with this you can override the attribute accessor in the model e.g. you present product_names in a capitlalized form even if they are stored lower case # Always titleize product names when showing def name read_attribute(:name).titleize end Another example, you''re seriously old school and believe only capital letters should be in databases def name=(name) write_attribute(:name, name.upcase) end Another technique would be to create a virtual attribute, so you can have two representations of the same value. For example a price and a currency_price where both refer to the same attribute but one deals with an integer and the other deals with nicely formatted prices. HTH 2008/12/19 James Byrne <lists at ruby-forum.com>> I have asked about this issue on several different mailing lists and > have had no response. If anyone here can offer some advice then I would > be much obliged. > > I have a feature that essentially says: > > Given I have a user "myuser" > When I fill in "User Name" with "MyUser" > And I press "Login" > Then I should find a user "myuser" > And I should be logged in > > The steps definitions for this are all quite conventional and at the > moment "Then I should find the user "myuser"" is failing, as expected. > > My question is: What is best practice with respect to normalizing form > input data? My feeling is that this sort of thing belongs in the model > but I cannot see a way to get this to work. In short, how to implement > this feature? > > I have extended String with a method called hll_keycase which preforms > the desired normalization. The setter for Users.username is overridden > in the model and the stored values in the database are all properly > normalized. But, it seems to me at the moment that the only place to > normalize form input data for the SELECT required to determine if the > username exists or not is either in the form or in the controller. Is > that the case? > > This has to be a recurring issue for data input forms and yet I can find > very few resources on the web that address this issue at all, and those > are often terse to the point of unintelligible. > > Not exactly a test issue but I really could use some guidance with this > as whatever technique I finally adopt will pervade the entire project. > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081219/5a19bbcd/attachment.html>
Thanks for the responses. For some reason they showed up in the digest email and yet have still not made it to the RSpec forum at Ruby_forum.com. I have been trying variants of these suggestions, indeed my very first approach was: def username @username.hll_keycase end However, I am working with authlogic and the UserSession Class of that gem throws an error complaining about a missing username= method when I provide the username method. When I provide username= then it complains about a missing password= method. At the time that I asked my question here I was trying to determine if there was something fundamentally wrong with my approach. Evidently this is not the case so I have now contacted the author directly since these issues are definitely outside the scope of this mailing list. Many thanks for the advice. Regards, -- Posted via http://www.ruby-forum.com/.
Andrew Premdas wrote:> You can use read_attribute and write_attribute in models to do this sort > of thing - though I''m not really clear exactly what it is you''re trying > to do. > I don''t think normalising is quite the right term here.Ahh. Well when I was working with sendmail email addresses the practice was called munging. But I believe that text normalization is defined as the practice of modifying any arbitrary text to a standard representation. In this case user logins are all stored as lowercase, whitespace trimmed, left-shifted, single spaced token delimited, phrases. So that MYUSER == MyUser == myuser. It avoids much unhappiness with users. -- Posted via http://www.ruby-forum.com/.