Рельсы:Проверяет уникальность области видимости по дате
-
19-09-2019 - |
Вопрос
У меня есть модель Rails, которая должна разрешать сохранение / обновление модели только один раз в день для каждого пользователя.У меня есть обратный вызов, чтобы выполнить поиск по пользователю и дате, а затем добавить к ошибкам, но это некрасиво и не похоже на rails.У меня есть типичные столбцы created_at / updated_at (и временная часть значительна / мне нужно сохранить ее).
Так что я полагаю, что мог бы либо:
1) Создайте другой атрибут модели, который является просто датой создания и областью действия по нему (bleh)
2) Используйте атрибут :scope, но каким-то образом получите только часть даты created_at , напримерvalidates_uniqueness_of :user, :scope => :created_at.to_date (очевидно, не работает)
3) Подтвердите, если => Proc.new{ |o| Finder, который соответствует моему существующему обратному вызову } (грубо)
http://ar.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M000086
Их не будет подавляющего числа, но я бы предпочел, чтобы это было сделано на SQL, а не на Ruby (по очевидным причинам масштабируемости).
Есть какие-нибудь мысли?Есть ли лучший способ?
Решение
Вы также можете написать свой собственный метод validates.Это довольно легко.И в пользовательском методе проверки, date_trunc дата выполнения (Postgresql) может быть использован для поиска существующих записей за требуемый промежуток времени.date_trunc также может быть параметризован (например, час, день, неделя, месяц).
Вместо date_trunc для поиска конфликтующей записи можно использовать простое условие.например ,["идентификатор пользователя = ?И updated_at >= ?", self.user_id, Time.now.beginning_of_day] И я предполагаю, что поиск этой записи должен быть быстрее, потому что она может использовать индекс.
Другие советы
В итоге я использовал conditions
вариант с validates_uniqueness_of
и передаю ему лямбда-код, который ограничивает проверяемые записи только теми, которые были на сегодняшний день.
class AttendanceRecord < ActiveRecord::Base
validates_uniqueness_of :user_id, conditions: { -> { where("DATE(created_at) = ?", Date.today) } }
end