Rails: unicité de scope par Valide la date
-
19-09-2019 - |
Question
J'ai un modèle Rails qui ne devrait permettre l'enregistrement / mise à jour d'un modèle une fois par jour par utilisateur. J'ai un rappel pour faire la Recherche par l'utilisateur et la date puis ajouter des erreurs, mais ce qui est laid et se sent un-rails-comme. Je created_at typique / updated_at colonnes (et la partie de temps est importante / je dois le garder).
Je me dis que je pouvais soit:
1) Créer un autre attribut de modèle qui est juste la date de création et la portée par cette (bleh)
2) Utilisez: attribut scope, mais en quelque sorte obtenir juste la partie date de created_at, par exemple validates_uniqueness_of: utilisateur,: scope =>: created_at.to_date (ne fonctionne pas, évidemment)
3) Valider moins => Proc.new {| o | Finder qui correspond à mon rappel existant} (brut)
http://ar.rubyonrails.org/classes/ActiveRecord /Validations/ClassMethods.html#M000086
Il n'y aura pas un très grand nombre d'entre eux, mais je préfère que cela se fasse dans SQL au lieu de Ruby (pour des raisons évidentes d'évolutivité).
Toutes les pensées? Y at-il une meilleure façon?
La solution
Vous pouvez également écrire votre propre méthode Valide. Ceci est tout à fait facile. Et dans la méthode de validation personnalisée, date_trunc (Postgresql) peut être utilisé pour trouver des enregistrements existants dans la durée de temps nécessaire. date_trunc peut également être paramétrées (e.g.hour, jour, semaine, mois).
Au lieu de date_trunc une condition simple peut être utilisé pour trouver le dossier en conflit. par exemple. [ "User_id = ET updated_at> =?", Self.user_id, Time.now.beginning_of_day] Et je suppose que ce disque semble être plus rapide up devrait, car il peut utiliser un index.
Autres conseils
Je fini par utiliser le conditions
avec l'option validates_uniqueness_of
et en le passant lambda qui limite les dossiers vérifiés juste ceux d'aujourd'hui.
class AttendanceRecord < ActiveRecord::Base
validates_uniqueness_of :user_id, conditions: { -> { where("DATE(created_at) = ?", Date.today) } }
end