Active Record - Znajdź rekordy, które zostały utworzone wcześniej

87

Chcę uzyskać wszystkie rekordy, w których pole created_at jest mniejsze niż dzisiaj (data). Czy jest coś takiego:

MyTable.find_by_created_at(< 2.days.ago)
Sayuj
źródło

Odpowiedzi:

167

Korzystanie z ActiveRecord w standardowy sposób:

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

Korzystanie z podstawowego interfejsu Arel :

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

Nakładanie cienkiej warstwy na Arel:

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

Za pomocą squeel :

MyModel.where { created_at < 2.days.ago }
tokland
źródło
dzięki!. Jeśli potrzebuję wszystkich rekordów z MyTable1, które są relacjami jeden do jednego z MyTable pod tym samym warunkiem, jak napisać zapytanie? Miałem na myśli coś w stylu, MyTable1.where(MyTable[:created_at] < Time.now)czy to możliwe?
Sayuj
Tak, ustawiłem relację klasy rekordu aktywnego.
Sayuj
11

Aby uzyskać wszystkie rekordy MyTableutworzone do 2 dni temu:

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

Zauważ, że możesz również szukać rekordów z polami zawierającymi pola w przyszłości w podobny sposób, tj. Aby uzyskać wszystkie rekordy MyTablez event_dateco najmniej 2 dni od teraz:

MyTable.where(event_date: 2.days.from_now..DateTime::Infinity.new)
Andreas
źródło
To daje"created_at" BETWEEN $1 AND $2 [["created_at", "4713-01-01 BC"], ["created_at", "2020-03-31 21:43:28.113759"]]
Pavel Chuchuva
2

Innym sposobem jest utworzenie zakresu w MyModellub przy ApplicationRecordużyciu interfejsu Arel , takiego jak tokland sugerowany w jego odpowiedzi :

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

Przykładowe wykorzystanie zakresu:

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

W przypadku wszystkich przewidywań sprawdź dokumentację lub kod źródłowy . Ten zakres nie przerywa wherełańcucha. Oznacza to, że możesz również:

MyModel.custom_scope1.arel(:created_at, :lt, 2.days.ago).arel(:updated_at, :gt, 2.days.ago).custom_scope2
3limin4t0r
źródło
Fantastyczny pomysł. Ale ActiveRecord::Relationdefiniuje metodę instancji o nazwie, arelco oznacza, że ​​wystarczy wybrać inną nazwę.
M-Dahab
-36

Time.now odnosi się teraz lub w tej chwili. Aby znaleźć wszystkich użytkowników wcześniej, po prostu użyj

@users = User.all

Spowoduje to znalezienie wszystkich użytkowników wcześniejszych w tej chwili i wykluczenie przyszłych użytkowników lub użytkowników, którzy dołączą po Time.now

Homer Jon
źródło
1
Time.now to nie to samo, co Today
John Naegle