Jak zdobyć rekord utworzony dzisiaj przez rails activerecord?


Odpowiedzi:


220
Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

PS: Ta odpowiedź została zmodyfikowana, ponieważ odpowiedź Harisha Shetty była lepsza niż moja. Ponieważ moja odpowiedź jest akceptowana. Zaktualizowałem tę odpowiedź dla wsparcia społeczności


4
Można zrobić Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira

1
Nie ma sensu sprawdzać, czy coś powstało przed końcem dnia dzisiejszego (ponieważ jutro jeszcze się nie wydarzyło).
jakeonrails

4
Chociaż Post.where("created_at >= ?", Time.zone.now.beginning_of_day)jest bardzo sprytny, poparłbym Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Jest sens robienia tego, aby manipulować czasem. Na przykład, jeśli testujesz, prawdopodobnie będziesz manipulować czasem, a wtedy pierwsza opcja nie zadziała. Chcesz uniknąć tego rodzaju przyszłych możliwych niepowodzeń, które prawdopodobnie zajmie trochę czasu debugowania.
lucasarruda

123

Wiem, że to pytanie ma akceptowaną odpowiedź. Rozwiązanie zaproponowane w zaakceptowanej odpowiedzi może powodować problemy z wydajnością, gdy rozmiar tabeli wzrośnie.

Zazwyczaj w przypadku wyszukiwania na podstawie created_atkolumny dodaj indeks do tabeli w pliku migracji.

add_index :posts, :created_at

Teraz, aby wyszukać rekordy utworzone dzisiaj:

Szyny 3/4

Post.where("created_at >= ?", Time.zone.now.beginning_of_day)

Aby wyszukać posty utworzone w określonym dniu.

Post.where(:created_at => (date.beginning_of_day..date.end_of_day))

--------- LUB -------------

Dodaj metodę statyczną do swojego modelu

class Post < ActiveRecord::Base
  def self.today
    where("created_at >= ?", Time.zone.now.beginning_of_day)
  end
end

Post.today #returns posts today

Szyny 2

Post.all(:conditions => ["created_at >= ?", Time.zone.now.beginning_of_day])

--------- LUB -------------

Dodaj named_scope do swojego modelu

class Post < ActiveRecord::Base    
  named_scope :today, lambda { 
    {
      :conditions => ["created_at >= ?", Time.zone.now.beginning_of_day]
    }
  }
end

Post.today #returns posts today

1
Świetna uwaga dotycząca indeksowania. Chciałem tylko wyjaśnić, że scopeprzykład w tym poście dotyczy tylko Rails 3, ponieważ wygląda na to, że znajduje się pod nagłówkiem Rails 2. W Railsach 2 powinieneś użyć named_scopezamiast scope. Ponadto, w Railsach 3, możesz równoważnie użyć metody klasy, def self.today where("created_at >= ?", Time.now.beginning_of_day) end która prawdopodobnie jest czystsza niż użycie zasięgu w tym przypadku, ponieważ pozwala ci zrezygnować z lambdy.
evanrmurphy

@evanrmurphy, Dzięki za zwrócenie uwagi. Naprawiłem odpowiedź.
Harish Shetty

@evanrmurphy może / czy powinieneś zmienić swój komentarz z „Tylko Rails 3” na „Rails 3 i nowsze”?
kaichanvong

@kaichanvong Nie jestem zaznajomiony z Rails 4, więc chciałbym powiedzieć „Rails 3 (i większe?)”, ale SO nie pozwoli mi edytować komentarza: - /
evanrmurphy

30

MySQL:

Model.all :condition => ["DATE(created_at) = ?", Date.today] # rails 2
Model.where("DATE(created_at) = ?", Date.today) # rails 3

PostgreSQL:

Model.all :condition => ["created_at::date = ?", Date.today] # rails 2
Model.where("created_at::date = ?", Date.today) # rails 3

19

Odpowiedź Mohita Jaina dostosowana do Rails3

Model.where "DATE(created_at) = DATE(?)", Time.now

16

Rails 5.1 ma all_daypomocnika, który jest tutaj przydatny.

Post.where(created_at: Date.today.all_day)

lub

Post.where(created_at: Date.parse("YYYY-MM-DD").all_day)

9

Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)

To „namescopes” atrybut z rozszerzeniem table_name.


5

model.rb

scope :posted_today, -> { posted_between_period(Time.now.midnight, Time.now.end_of_day) }

posts_controller.rb

Post.posted_today

2
@Pathiv, between_periodwygląda interesująco. Nie znalazłem do tego żadnej dokumentacji. Czy możesz podać link? W jaki sposób szyny wybierają kolumnę do porównania?
Harish Shetty

1

Z jakiegoś powodu żadne inne rozwiązanie w tym poście ani inne na StackOverflow nie działały dla mnie (używając Rails 4.2.4 i Ruby 2.2.3p173). To jedyne zapytanie, które udało mi się uzyskać, aby pracować z moją bazą danych Postgres:

Post.where("created_at >= TIMESTAMP 'now'")

-1

Aby zapytać o rekordy utworzone od dzisiaj

Użyj zakresu z arel

class Post < ActiveRecord::Base    
  scope :create_from_today, -> {
    where(arel_table[:created_at].gteq(Time.zone.now.beginning_of_day))
  }
end

Wtedy możemy to wykorzystać

today_posts = Post.created_from_today

where('created_at >= now()')znalazłby tylko elementy, w których w przyszłości znajdował się atrybut created_at.
PR Whitehead

Tak, usunąłbym to z odpowiedzi, miłe dzięki
Hieu Pham

Problem, który teraz masz, polega na tym, że rekordy, które są oznaczone przyszłymi datami, byłyby prezentowane tak samo jak dzisiejsze. Jeśli próbujesz uniknąć używania między, powinieneś również określić .lteq(Time.zone.now.end_of_day)).
PR Whitehead

-4

W railsach 4.2.3 do pobierania rekordów utworzonych dzisiaj za pomocą mysql użyj następującego.

@usergoals = Goal.where ("userid =: userid and Date (created_at) =: date", {userid: params [: id], date: Date.today})

tutaj używam wielu warunków, jeśli chcesz, możesz je edytować dla jednego warunku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.