Enregistrement actif - Rechercher des enregistrements qui ont été créés_at avant aujourd'hui

87

Je veux obtenir tous les enregistrements où le champ created_at est inférieur à aujourd'hui (une date). Y a-t-il quelque chose comme:

MyTable.find_by_created_at(< 2.days.ago)
Sayuj
la source

Réponses:

167

Utilisation d' ActiveRecord de manière standard:

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

Utilisation de l' interface Arel sous-jacente :

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

En utilisant une fine couche sur Arel:

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

Utilisation de squeel :

MyModel.where { created_at < 2.days.ago }
tokland
la source
Merci!. Si j'ai besoin de tous les enregistrements de MyTable1 qui sont une à une relation avec MyTable sur la même condition, comment écrire la requête? Je parlais de quelque chose comme MyTable1.where(MyTable[:created_at] < Time.now)est-ce possible?
Sayuj
Oui, j'ai défini la classe d'enregistrement active de relation.
Sayuj
11

Pour obtenir tous les enregistrements MyTablecréés jusqu'à il y a 2 jours:

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

Notez que vous pouvez également rechercher des enregistrements avec des champs contenant des champs dans le futur de la même manière, c'est-à-dire pour obtenir tous les enregistrements MyTableavec event_dateau moins 2 jours à partir de maintenant:

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

Une autre façon est de créer une portée dans MyModelou en ApplicationRecordutilisant l' interface Arel comme tokland suggéré dans sa réponse comme ceci:

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

Exemple d'utilisation de la portée:

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

Pour toutes les prédications, consultez la documentation ou le code source . Cette portée ne rompt pas la wherechaîne. Cela signifie que vous pouvez également faire:

MyModel.custom_scope1.arel(:created_at, :lt, 2.days.ago).arel(:updated_at, :gt, 2.days.ago).custom_scope2
3limin4t0r
la source
Fantastique idée. Mais, ActiveRecord::Relationdéfinit une méthode d'instance avec le nom, arelce qui signifie que vous devez simplement choisir un nom différent.
M-Dahab le
-36

Time.now fait référence à maintenant ou à cette seconde. Donc, pour trouver tous les utilisateurs avant maintenant, utilisez simplement

@users = User.all

Cela trouvera tous les utilisateurs avant maintenant et exclura les futurs utilisateurs ou utilisateurs qui se joindront après Time.now

Homer Jon
la source
1
Time.now n'est pas la même chose qu'aujourd'hui
John Naegle