views:

87

answers:

4

I'm trying to validate wether a Model.category equals any existing Category name

unless Category.exists?(:name => self.category.downcase)

I had to put downcase in this to ensure all of them were downcased so they could match up as strings. But its a big server hit to update the attribute before_save, and I was thinking of just matching them via regexp. Something like this

unless Category.exists?(:name => /#{self.category}/ }

Is there something like that possible? Or is there a better way to do this?

A: 

I don't know how to program in Ruby, but it certainly can be achieved by concatenating string with regexp with your string and then running regexp.

Tomasz Kowalczyk
how do you add the /i case insensitivity option to a regexp?
Trip
+2  A: 
x = 'fluffy'
Regexp.new x.to_s

Perhaps there's a better way.

vise
?? I don't understand, sorry. :(
Trip
`/expression/` is a syntactic sugar for the `Regexp` class. With the latter you can explicitly create a new regular expression. So `Regexp.new(self.category, Regexp::IGNORECASE)` is what you need (but you can also use string interpolation for it). More information you can find in the documentation. http://ruby-doc.org/core/classes/Regexp.html
floatless
Thanks Foatless. Great advice :D Trouble is that returns a regexp, and not the var downcased.
Trip
I don't quite understand. What do you try to accomplish?
floatless
I want to return the result "JiMMy" to be "jimmy" not "/JiMMy/".
Trip
+3  A: 

Yep, you can use variable interpolation in a regex.

>> s = "thing"
=> "thing"
>> r = /#{s}/
=> /thing/
mipadi
Awesome, hey you wouldn't know how to add the case insensitivity option /i to your regexp, do you?
Trip
Just add an 'i': r = /#{s}/i
steenslag
Hmm.. it seems like all this interpolation is just returning a regexp, and not the end result of what i want.
Trip
+1  A: 

I cant understand what is your real problem here with downcasing but I suppose that you had to downcase existing categories first before comparison. I suppose regexp wont help here because as "=>" in conditions is exact case sensitive comparison (default in DBs) and regexp is not supported by AR. You should do it another way:

PostgreSQL:

books = Book.find :all, :conditions => [ "authors ILIKE ?", "smith" ]

Mysql:

author = "Smith".downcase
books = Book.find :all, :conditions => [ "LOWER(authors) LIKE ?", "#{author}" ]

or

books = Book.find :all, :conditions => [ "authors LIKE ? COLLATE utf8_general_ci", "smith"]

The exist? method should work with :conditions parameter as above. If that causes any DB hit for you e.g. you have milions of categories. Then you should create separate column with downcased name and compare it with simple "=>" condition.

gertas
Thanks Gertas! Great first post, welcome to Stack
Trip
Thanks, also make sure that leading and ending spaces are removed (String#strip or String#strip!), users type in many strange things.
gertas