Active Record - Encontre registros que foram criados antes de hoje

87

Quero obter todos os registros em que o campo created_at seja menor que hoje (uma data). Existe algo como:

MyTable.find_by_created_at(< 2.days.ago)
Sayuj
fonte

Respostas:

167

Usando ActiveRecord da maneira padrão:

MyModel.where("created_at < ?", 2.days.ago)

Usando a interface Arel subjacente :

MyModel.where(MyModel.arel_table[:created_at].lt(2.days.ago))

Usando uma camada fina sobre Arel:

MyModel.where(MyModel[:created_at] < 2.days.ago)

Usando squeel :

MyModel.where { created_at < 2.days.ago }
Tokland
fonte
obrigado!. Se eu precisar de todos os registros de MinhaTabela1 que são um para um relação com MinhaTabela na mesma condição, como escrever a consulta? Eu estava me referindo a algo como MyTable1.where(MyTable[:created_at] < Time.now)é possível?
Sayuj
Sim, eu configurei a classe de registro ativo da relação.
Sayuj
11

Para obter todos os registros MyTablecriados até 2 dias atrás:

MyTable.where(created_at: Date.new..2.days.ago)

Observe que você também pode procurar registros com campos contendo campos no futuro de maneira semelhante, ou seja, obter todos os registros MyTablecom event_datepelo menos 2 dias a partir de agora:

MyTable.where(event_date: 2.days.from_now..DateTime::Infinity.new)
Andreas
fonte
Isto produz"created_at" BETWEEN $1 AND $2 [["created_at", "4713-01-01 BC"], ["created_at", "2020-03-31 21:43:28.113759"]]
Pavel Chuchuva
2

Outra maneira é criar um escopo em MyModelou no ApplicationRecorduso da interface Arel como tokland sugerido em sua resposta assim:

scope :arel, ->(column, predication, *args) { where(arel_table[column].public_send(predication, *args)) }

Exemplo de uso do escopo:

MyModel.arel(:created_at, :lt, 2.days.ago)

Para todas as previsões, verifique a documentação ou o código-fonte . Este escopo não quebra a wherecadeia. Isso significa que você também pode fazer:

MyModel.custom_scope1.arel(:created_at, :lt, 2.days.ago).arel(:updated_at, :gt, 2.days.ago).custom_scope2
3limin4t0r
fonte
Idéia fantástica. Mas, ActiveRecord::Relationdefine um método de instância com o nome, o arelque significa que você só precisa escolher um nome diferente.
M-Dahab
-36

Time.now se refere a agora ou neste exato segundo. Então, para encontrar todos os usuários antes de agora, basta usar

@users = User.all

Isso encontrará todos os usuários anteriores agora e excluirá futuros usuários ou usuários que ingressarem após Time.now

Homer Jon
fonte
1
Time.now não é o mesmo que Today
John Naegle