Нечувствительный к регистру find_or_create_by_whatever

Я хочу смочь сделать 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), но это кажется намного более твердым реализовать

6
задан Tom Lehman 12 March 2010 в 22:12
поделиться

3 ответа

Этот ответ предназначен для дополнительных вопросов, заданных в комментариях к вопросу.

Вы не сможете вызвать стандартный 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)
7
ответ дан 8 December 2019 в 03:26
поделиться

Вы должны создать индекс на основе базы данных.

postgreSQL

Создайте индекс в нижнем регистре в столбце имя_ исполнителя .

CREATE INDEX lower_artists_name ON artists(lower(artist_name))

mySQL

При поиске учитывается регистр

sqlLite

Создайте индекс для столбца имя_ исполнителя с параметром сопоставления

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: поиск без учета регистра

5
ответ дан 8 December 2019 в 03:26
поделиться

Об этом говорили здесь . Никто не смог придумать решение лучше, чем ваше :)

1
ответ дан 8 December 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: