У меня есть проверка ActiveRecord для некоторых записей, которые по умолчанию автоматически блокируют мое приложение-рельсы несколько версий записей с одинаковым значением строки следующим образом:Ruby: Как сохранить динамически сгенерированный список на уровне класса, так что список вычисляется только один раз и ТОЛЬКО ЕСЛИ класс вызван на
class Boat < ActiveRecord::Base# not actual class name, but I like boating
validates :boatname, :uniqueness => true
end
Я хотел бы добавить before_validation
обратные вызов для моей модели, как так ...
require 'highline/import' #simplifies command prompt response code
class Boat < ActiveRecord::Base
validates :boatname
before_validation do |r|
pre_existing = Boat.find_by_boatname(r.boatname)
if pre_existing
puts "whoa! found a boat that already exists with the name '#{r.boatname}':"
ap pre_existing #pretty prints the column names and values
resp = ask("press 'o' to overwrite, 'm' to modify the new boat name so it gets added")
if resp == "o"
#..code handling responses
end
end
Но это вычислительно дорого абсурдного степень. Я думал об обращении с ним, как это, что приводит нас к моему актуальному вопросу:
require 'highline/import' #simplifies command prompt response code
class Boat < ActiveRecord::Base
validates :boatname
@@existing_boats ||= all.map(&:boatname)
before_validation do |r|
if @@existing_boats.include?(r.boatname)
puts "whoa! found a boat that already exists with the name '#{r.boatname}':"
ap pre_existing #pretty prints the column names and values
resp = ask("press 'o' to overwrite, 'm' to modify the new boat name so it gets added")
if resp == "o"
#..code handling responses
end
end
Это лучший способ справиться с что-то вроде этого? Соответствует ли он моим критериям загрузки только один раз за экземпляр ruby / rails и только если класс вызван? Я подумал, может быть, мне придется поместить компонент all.map(&:boatname)
в лямбда или proc, чтобы предотвратить его загрузку каждый раз, когда рельсы инициализированы, но я не уверен, что это необходимо.
Принимая общую критику в отношении моего проектного подхода, но это не цель вопроса.
Ваша вторая версия, вероятно, дороже, не менее (при условии, что у вас есть указатель на имя лодки) –
Вы делаете это неправильно. Вещь, которая пытается создать «Boat's», должна выполнять «перезапись/изменение». У вас также должен быть уникальный индекс в 'boatname' в вашей базе данных, этот индекс должен сделать проверку подлинности существования очень быстрой. –
Спасибо @FrederickCheung, этот комментарий стоил того, чтобы расспрашивать вопрос –