My product model contains some items
Product.first
=> #<Product id: 10, name: "Blue jeans" >
I'm now importing some product parameters from another dataset, but there are inconsistencies in the spelling of the names. For instance, in the other dataset, Blue jeans
could be spelled Blue Jeans
.
I wanted to Product.find_or_create_by_name("Blue Jeans")
, but this will create a new product, almost identical to the first. What are my options if I want to find and compare the lowercased name.
Performance issues is not really important here: There are only 100-200 products, and I want to run this as a migration that imports the data.
Any ideas?
Case-insensitive searching comes built-in with Rails. It accounts for differences in database implementations. Use either the built-in Arel library, or a gem like Squeel.
Quoting from the SQLite documentation:
...which I didn't know.But it works:
So you could do something like this:
Not
#find_or_create
, I know, and it may not be very cross-database friendly, but worth looking at?Another approach that no one has mentioned is to add case insensitive finders into ActiveRecord::Base. Details can be found here. The advantage of this approach is that you don't have to modify every model, and you don't have to add the
lower()
clause to all your case insensitive queries, you just use a different finder method instead.Find_or_create is now deprecated, you should use an AR Relation instead plus first_or_create, like so:
This will return the first matched object, or create one for you if none exists.
This is a complete setup in Rails, for my own reference. I'm happy if it helps you too.
the query:
the validator:
the index (answer from Case-insensitive unique index in Rails/ActiveRecord?):
I wish there was a more beautiful way to do the first and the last, but then again, Rails and ActiveRecord is open source, we shouldn't complain - we can implement it ourselves and send pull request.
Assuming that you use mysql, you could use fields that are not case sensitive: http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html