I want to strip out embedded separators from a harmonized tariff code
before validating it. I thought (naively) that I could do this:
class Product < ActiveRecord::Base
validates_format_of :hs_class_code, :with =>
/\A(\d{6}|\d{8}|\d{10})?\Z/
protected
def before_validation
hs_class_code = hs_class_code.tr(".","").strip if
!hs_class_code.nil?
end
but evidently hs_class_code is always nil. What is the proper syntax to
use here?
Thanks,
--
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
-~----------~----~----~----~------~----~------~--~---
Try this:
class Product < ActiveRecord::Base
validates_format_of :hs_class_code, :with =>
/\A(\d{6}|\d{8}|\d{10})?\Z/
before_validation :clean_tariff_code
protected
def clean_tariff_code
self.hs_class_code.gsub!(".","") unless
self.hs_class_code.nil?
end
It makes it more clear if you name the method. Also, it is a good idea
to use self. to be sure that what are intended to be accessor method
calls are not interpreted as local variables.
Another problem was the use of tr which returns nil if no substitution
is made. The was your initial method was written, if hs_class_code did
not contain the "." character, the result would be to call strip on
nil.
Hope this helps
-Bill
James Byrne wrote:> I want to strip out embedded separators from a harmonized tariff code
> before validating it. I thought (naively) that I could do this:
>
> class Product < ActiveRecord::Base
>
> validates_format_of :hs_class_code, :with =>
> /\A(\d{6}|\d{8}|\d{10})?\Z/
>
> protected
>
> def before_validation
> hs_class_code = hs_class_code.tr(".","").strip if
> !hs_class_code.nil?
> end
>
> but evidently hs_class_code is always nil. What is the proper syntax to
> use here?
>
> Thanks,
>
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
William Pratt wrote:> Try this: > > class Product < ActiveRecord::Base > > validates_format_of :hs_class_code, :with => > /\A(\d{6}|\d{8}|\d{10})?\Z/ > > before_validation :clean_tariff_code > > protected > > def clean_tariff_code > self.hs_class_code.gsub!(".","") unless self.hs_class_code.nil? > end > > It makes it more clear if you name the method. Also, it is a good idea > to use self. to be sure that what are intended to be accessor method > calls are not interpreted as local variables. >Thanks, I am having a deal of difficulty in mentally switching between symbols and such in this context. This makes it very clear what I need to do in similar situation. Yet doubtless I will continue to have problems like this for a while yet.> Another problem was the use of tr which returns nil if no substitution > is made. The was your initial method was written, if hs_class_code did > not contain the "." character, the result would be to call strip on nil. >I believe that .tr returns the original string while it is .tr! that returns nil in this case. (paralleling .sub and .sub!) Thanks for you help. It is greatly appreciated. Jim -- 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 -~----------~----~----~----~------~----~------~--~---
James Byrne wrote:> William Pratt wrote: >> Try this: >> >> class Product < ActiveRecord::Base >> >> validates_format_of :hs_class_code, :with => >> /\A(\d{6}|\d{8}|\d{10})?\Z/ >> >> before_validation :clean_tariff_code >> >> protected >> >> def clean_tariff_code >> self.hs_class_code.gsub!(".","") unless self.hs_class_code.nil? >> end >>How would one turn this into a generalized case? Given this: before_validation :delouse, :hs_class_code, :with => /\A<regex>\Z/ would this work? protected def delouse(attr,regx) self.(attr).gssub(regx,"") unless self.(attr).nil? end -- 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 -~----------~----~----~----~------~----~------~--~---
Well, I am not sure about :with on before_validation as I don''t see it
in the docs or examples anywhere, but I''m not saying it won''t
work, I
just don''t know. What I can do is show you how I do it and others may
chime in with alternatives / better solutions if some exist. First, what
I think you are asking is how to generically call your clean method by
passing in the attribute and the regex to use. Here are two ways, one
more verbose than the other, but it''s more self documenting.
before_validation :delouse_hs_class_code
before_validation :delouse_another_one
protected
def delouse_another_one
delouse(:another_one,/\"/)
end
def delouse_hs_class_code
delouse(:hs_class_code,/\./)
end
def delouse(attr,regex)
self.send(attr).gsub!(regex,"") unless self.send(attr).nil?
end
Or you could use Proc''s
before_validation Proc.new{|o| o.delouse(:hs_class_code,/\./)}
before_validation Proc.new{|o| o.delouse(:another_one,/\"/)}
protected
def delouse(attr,regex)
self.send(attr).gsub!(regex,"") unless self.send(attr).nil?
end
This should get you going in the right direction. This is just a mock up
that I didn''t test exactly and this was also written before my first
cup
of coffee :)
HTH,
-Bill
James Byrne wrote:> James Byrne wrote:
>
>> William Pratt wrote:
>>
>>> Try this:
>>>
>>> class Product < ActiveRecord::Base
>>>
>>> validates_format_of :hs_class_code, :with =>
>>> /\A(\d{6}|\d{8}|\d{10})?\Z/
>>>
>>> before_validation :clean_tariff_code
>>>
>>> protected
>>>
>>> def clean_tariff_code
>>> self.hs_class_code.gsub!(".","") unless
self.hs_class_code.nil?
>>> end
>>>
>>>
>
> How would one turn this into a generalized case? Given this:
>
> before_validation :delouse, :hs_class_code, :with =>
> /\A<regex>\Z/
>
> would this work?
>
> protected
>
> def delouse(attr,regx)
> self.(attr).gssub(regx,"") unless self.(attr).nil?
> end
>
>
--
Sincerely,
William Pratt
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---
William Pratt wrote:> This should get you going in the right direction. This is just a mock up > that I didn''t test exactly and this was also written before my first cup > of coffee :) >I will try this approach out later when I get a minute to myself. However, I found this sample in the callback module documentation. class CreditCard < ActiveRecord::Base # Strip everything but digits, so the user can specify "555 234 34" or # "5552-3434" or both will mean "55523434" def before_validation_on_create self.number = number.gsub(/[^0-9]/, "") if attribute_present?("number") end end Which seems a more comprehensive regex to use for the purpose I intend (retain digits only). I suppose something like digits_only is a more descriptive method name than delouse as well. There does not seem to be any way to pass any additional parameters beyond the first to the before_validate call. -- 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 -~----------~----~----~----~------~----~------~--~---
As for the regex, I agree, always use what you want to allow rather than attempting to guess everything you need to take out. In the examples, I was just using what you had in the original method. As far as passing options, you will need to use one of the 2 methods I presented, both of which will allow multiple arguments. -Bill James Byrne wrote:> William Pratt wrote: > > >> This should get you going in the right direction. This is just a mock up >> that I didn''t test exactly and this was also written before my first cup >> of coffee :) >> >> > > I will try this approach out later when I get a minute to myself. > However, I found this sample in the callback module documentation. > > class CreditCard < ActiveRecord::Base > # Strip everything but digits, so the user can specify "555 234 34" > or > # "5552-3434" or both will mean "55523434" > def before_validation_on_create > self.number = number.gsub(/[^0-9]/, "") if > attribute_present?("number") > end > end > > Which seems a more comprehensive regex to use for the purpose I intend > (retain digits only). I suppose something like digits_only is a more > descriptive method name than delouse as well. There does not seem to be > any way to pass any additional parameters beyond the first to the > before_validate call. >-- Sincerely, William Pratt --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
This is what I ended up with. It seems to work.
before_validation :digits_only_hs_class_code
protected
# Strip everything except digits from input string
def digits_only(attr)
attr.gsub(/[^0-9]/, "") unless attr.nil?
end
def digits_only_hs_class_code
# only do this if not nil
self.hs_class_code = digits_only(self.hs_class_code) if
self.hs_class_code
end
--
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
-~----------~----~----~----~------~----~------~--~---