Я хочу смочь сделать 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)
, но это кажется намного более твердым реализовать
Этот ответ предназначен для дополнительных вопросов, заданных в комментариях к вопросу.
Вы не сможете вызвать стандартный 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)
Вы должны создать индекс на основе базы данных.
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))
Ссылка
Об этом говорили здесь . Никто не смог придумать решение лучше, чем ваше :)