Tom*_*man 6 ruby activerecord ruby-on-rails case-insensitive
我希望能够Artist.case_insensitive_find_or_create_by_name(artist_name)[1](并且它可以在sqlite和postgreSQL上工作)
实现这一目标的最佳方法是什么?现在我只是直接向Artist类中添加一个方法(有点难看,特别是如果我想在另一个类中使用此功能,但无论如何):
def self.case_insensitive_find_or_create_by_name(name)
first(:conditions => ['UPPER(name) = UPPER(?)', name]) || create(:name => name)
end
Run Code Online (Sandbox Code Playgroud)
[1]:理想情况下,这可能是Artist.find_or_create_by_name(artist_name, :case_sensitive => false),但这似乎更难实施
Eri*_*ipp 16
Rails 4为您提供了完成同样事情的方法:
Artist.where('lower(name) = ?', name.downcase).first_or_create(:name=>name)
这个答案是针对问题评论中提出的其他问题.
find_or_create_by_name如果覆盖该方法,则无法调用默认值.但您可以实现自己的,如下所示:
def self.find_or_create_by_name(*args)
options = args.extract_options!
options[:name] = args[0] if args[0].is_a?(String)
case_sensitive = options.delete(:case_sensitive)
conditions = case_sensitive ? ['name = ?', options[:name]] :
['UPPER(name) = ?', options[:name].upcase]
first(:conditions => conditions) || create(options)
end
Run Code Online (Sandbox Code Playgroud)
现在您可以调用重写方法,如下所示:
User.find_or_create_by_name("jack")
User.find_or_create_by_name("jack", :case_sensitive => true)
User.find_or_create_by_name("jack", :city=> "XXX", :zip => "1234")
User.find_or_create_by_name("jack", :zip => "1234", :case_sensitive => true)
Run Code Online (Sandbox Code Playgroud)
您必须基于数据库创建索引.
PostgreSQL的
在artist_name列上创建小写索引.
CREATE INDEX lower_artists_name ON artists(lower(artist_name))
Run Code Online (Sandbox Code Playgroud)
MySQL的
搜索不区分大小写
sqlLite
artist_name使用collate参数在列上创建索引
CREATE INDEX lower_artists_name ON artists( artist_name collate nocase)
Run Code Online (Sandbox Code Playgroud)
现在,您可以以独立于数据库的方式使用find_or_create:
find_or_create_by_artist_name(lower(artist_name))
Run Code Online (Sandbox Code Playgroud)
参考
| 归档时间: |
|
| 查看次数: |
4497 次 |
| 最近记录: |