Rails: Valida singularidade de escopo por data
-
19-09-2019 - |
Pergunta
Eu tenho um modelo Rails que só deve permitir poupar / atualização de um modelo de uma vez por dia por usuário. Eu tenho uma chamada de retorno para fazer o Find por usuário e data, em seguida, adicionar a erros, mas isso é feio e sente un-rails-like. Tenho a created_at típica / updated_at colunas (e a parte do tempo é significativo / I precisa mantê-lo).
Então, eu acho que eu poderia ou:
1) Criar outro atributo modelo que é apenas a data de criação eo alcance por que (bleh)
2) Utilize a: atributo scope mas de alguma forma obter apenas a parte de data created_at, por exemplo, validates_uniqueness_of: usuário,: ??scope =>: created_at.to_date (não funciona, obviamente)
3) Validar a menos => Proc.new {| o | Localizador que corresponde ao meu retorno existente} (bruto)
http://ar.rubyonrails.org/classes/ActiveRecord /Validations/ClassMethods.html#M000086
Não haverá um número esmagador destes, mas eu prefiro que ele é feito em SQL em vez de Ruby (por razões de escalabilidade óbvias).
Todos os pensamentos? Existe uma maneira melhor?
Solução
Você também pode escrever seu próprio método valida. Isto é bastante fácil . E no método de validação personalizada, date_trunc (PostgreSQL) pode ser usado para encontrar registros existentes no intervalo de tempo necessário. date_trunc também pode ser parametrizada (e.g.hour, dia, semana, mês).
Em vez de date_trunc uma condição simples pode ser usado para encontrar o registro conflitantes. por exemplo. [ "User_id =? E updated_at> =?", Self.user_id, Time.now.beginning_of_day] E eu acho que esse disco olhar para cima deve ser mais rápido porque ele pode usar um índice.
Outras dicas
Acabei usando a conditions
opção com validates_uniqueness_of
e passando-lambda que limita os registros verificados para apenas aqueles para hoje.
class AttendanceRecord < ActiveRecord::Base
validates_uniqueness_of :user_id, conditions: { -> { where("DATE(created_at) = ?", Date.today) } }
end