不区分大小写的 find_or_create_by_whatever

发布于 2024-08-24 18:39:24 字数 506 浏览 8 评论 0原文

我希望能够执行 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

[1]:嗯,理想情况下是Artist.find_or_create_by_name(artist_name, :case_sensitive => false),但这似乎更难实现

I want to be able to do Artist.case_insensitive_find_or_create_by_name(artist_name)[1] (and have it work on both sqlite and postgreSQL)

What's the best way to accomplish this? Right now I'm just adding a method directly to the Artist class (kind of ugly, especially if I want this functionality in another class, but whatever):

  def self.case_insensitive_find_or_create_by_name(name)
    first(:conditions => ['UPPER(name) = UPPER(?)', name]) || create(:name => name)
  end

[1]: Well, ideally it would be Artist.find_or_create_by_name(artist_name, :case_sensitive => false), but this seems much harder to implement

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晒暮凉 2024-08-31 18:39:24

Rails 4 为您提供了一种完成相同任务的方法:

Artist.where('lower(name) = ?', name.downcase).first_or_create(:name=>name)

Rails 4 gives you a way to accomplish the same thing:

Artist.where('lower(name) = ?', name.downcase).first_or_create(:name=>name)

魔法少女 2024-08-31 18:39:24

此答案是针对问题评论中提出的其他问题的。

如果您重写该方法,您将无法调用默认的 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

现在您可以调用重写的方法,如下所示:

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)

This answer is for the additional questions asked in the question comments.

You wont be able to call the default find_or_create_by_name if you override that method. But you can implement your own as shown below:

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

Now you can call the overridden method as follows:

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)
孤者何惧 2024-08-31 18:39:24

您必须根据数据库创建索引。

postgreSQL

artist_name 列上创建小写索引。

CREATE INDEX lower_artists_name ON artists(lower(artist_name))

mySQL

搜索不区分大小写

sqlLite

使用整理参数在 artist_name 列上创建索引

CREATE INDEX lower_artists_name ON artists( artist_name collate nocase)

现在您可以以与数据库无关的方式使用 find_or_create:

find_or_create_by_artist_name(lower(artist_name))

参考

PostgreSQL:不区分大小写的搜索

sqlLite:不区分大小写的搜索

You have to create an index based on the database.

postgreSQL

Create a lower case index on artist_name column.

CREATE INDEX lower_artists_name ON artists(lower(artist_name))

mySQL

Searches are case insensitive

sqlLite

Create a index on artist_name column with collate parameter

CREATE INDEX lower_artists_name ON artists( artist_name collate nocase)

Now you can use find_or_create in a DB independent manner:

find_or_create_by_artist_name(lower(artist_name))

Reference

PostgreSQL: Case insensitive search

sqlLite: Case insensitive search

陌路黄昏 2024-08-31 18:39:24

此处讨论了这一问题。没有人能想出比你更好的解决方案:)

Talked about this one here. No one was able to come up with a solution better than yours :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文