Rails: Convalida unicità di ambito per data
-
19-09-2019 - |
Domanda
Ho un modello Rails che dovrebbe solo permetterà il salvataggio / aggiornamento di un modello di una volta al giorno per utente. Ho un callback per fare la Ricerca da parte dell'utente e la data quindi aggiungere ad errori, ma questo è brutto e si sente un-rails-like. Ho la created_at tipica / updated_at colonne (e la parte di tempo è significativo / ho bisogno di tenerlo).
Quindi immagino Potevo:
1) Creare un altro attributo del modello che è solo la data di creazione e la portata da quel (bleh)
2) Utilizzare il: attributo scope ma in qualche modo ottenere solo la parte relativa alla data di created_at, per esempio validates_uniqueness_of: utente,: portata =>: created_at.to_date (non funziona, ovviamente)
3) Convalida a meno => {Proc.new | o | Finder che soddisfa la mia callback esistente} (lordo)
http://ar.rubyonrails.org/classes/ActiveRecord /Validations/ClassMethods.html#M000086
Non ci sarà un numero enorme di questi, ma io preferirei che si è fatto in SQL invece di Ruby (per ragioni di scalabilità ovvie).
Qualche idea? C'è un modo migliore?
Soluzione
È anche possibile scrivere il proprio metodo di Convalida. Questo è abbastanza facile . E nel metodo validate personalizzato, date_trunc (PostgreSQL) può essere utilizzato per trovare i record esistenti in lasso di tempo richiesto. date_trunc può essere anche parametrizzata (e.g.hour, giorno, settimana, mese).
Invece di date_trunc una semplice condizione può essere utilizzato per trovare record di conflitto. per esempio. [ "User_id =? E updated_at> =?", Self.user_id, Time.now.beginning_of_day] e credo che questo disco look up dovrebbe essere più veloce perché può utilizzare un indice.
Altri suggerimenti
Ho finito per usare il conditions
opzione con validates_uniqueness_of
e passandolo lambda che limita i record marcati solo a quelli per oggi.
class AttendanceRecord < ActiveRecord::Base
validates_uniqueness_of :user_id, conditions: { -> { where("DATE(created_at) = ?", Date.today) } }
end