Wie kann man heute einen Datensatz mit Rails Activerecord erstellen?

112

Wie soll ich die bedingte Anweisung schreiben, wenn ich alle heute erstellten Datensätze abrufen möchte?

Victor Lam
quelle

Antworten:

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

PS: Diese Antwort wurde geändert, da die Antwort von Harish Shetty besser war als meine. Als meine Antwort wird eine akzeptiert. Ich habe diese Antwort für die Community-Unterstützung aktualisiert

Mohit Jain
quelle
4
Man könnte Post.where machen (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira
1
Es macht keinen Sinn zu überprüfen, ob etwas vor dem Ende von heute erstellt wurde (da morgen noch nicht passiert ist).
Jakeonrails
4
Während Post.where("created_at >= ?", Time.zone.now.beginning_of_day)es sehr klug ist, würde ich unterstützen Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Es gibt einen Grund, wie Sie die Zeit manipulieren können. Wenn Sie beispielsweise testen, werden Sie wahrscheinlich die Zeit manipulieren, und dann funktioniert die erste Option nicht. Sie möchten diese Art von zukünftigem möglichen Fehler vermeiden, der wahrscheinlich einige Debug-Zeit in Anspruch nehmen wird.
Lucasarruda
121

Ich weiß, dass diese Frage eine akzeptierte Antwort hat. Die in der akzeptierten Antwort vorgeschlagene Lösung kann zu Leistungsproblemen führen, wenn die Tabellengröße zunimmt.

Wenn Sie Suchvorgänge basierend auf created_atSpalten durchführen, fügen Sie in der Regel einen Index für die Tabelle in Ihrer Migrationsdatei hinzu.

add_index :posts, :created_at

So suchen Sie nach heute erstellten Datensätzen:

Schienen 3/4

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

Zum Nachschlagen von Posts, die an einem bestimmten Tag erstellt wurden.

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

--------- ODER -------------

Fügen Sie Ihrem Modell eine statische Methode hinzu

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

Post.today #returns posts today

Schienen 2

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

--------- ODER -------------

Fügen Sie Ihrem Modell ein named_scope hinzu

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

Post.today #returns posts today
Harish Shetty
quelle
1
Toller Punkt zur Indizierung. Ich wollte nur klarstellen, dass das scopeBeispiel in diesem Beitrag nur für Rails 3 gilt, da es so aussieht, als ob es sich unter der Überschrift Rails 2 befindet. In Rails 2 müssten Sie named_scopeeher als verwenden scope. In Rails 3 können Sie auch eine Klassenmethode verwenden, def self.today where("created_at >= ?", Time.now.beginning_of_day) end die wahrscheinlich sauberer ist als die Verwendung eines Bereichs in diesem Fall, da Sie auf das Lambda verzichten können.
evanrmurphy
@evanrmurphy, Danke, dass du das bemerkt hast. Ich habe eine feste Antwort.
Harish Shetty
@evanrmurphy können / sollten Sie Ihren Kommentar von "nur Rails 3" auf "Rails 3 und höher" überarbeiten?
Kaichanvong
@kaichanvong Ich bin nicht mit Rails 4 vertraut, daher möchte ich "Rails 3 (und höher?)" sagen, aber SO kann ich den Kommentar nicht bearbeiten: - /
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
Jigfox
quelle
18

Mohit Jains Antwort für Rails3 angepasst

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

Rails 5.1 hat einen all_dayHelfer, der hier nützlich ist.

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

oder

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

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

Dieser "Namescopes" das Attribut mit dem table_name.

Rafael Oliveira
quelle
5

model.rb

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

posts_controller.rb

Post.posted_today
Parthiv
quelle
2
@Pathiv, between_periodsieht interessant aus. Ich habe keine Dokumentation dafür gefunden. Können Sie einen Link angeben? Wie wählen Schienen die Spalte zum Vergleich aus?
Harish Shetty
1

Aus irgendeinem Grund funktionierte keine der anderen Lösungen in diesem Beitrag oder andere in StackOverflow für mich (unter Verwendung von Rails 4.2.4 und Ruby 2.2.3p173). Dies ist die einzige Abfrage, die ich mit meiner Postgres-Datenbank bearbeiten konnte:

Post.where("created_at >= TIMESTAMP 'now'")
Tim S.
quelle
-1

Abfragen von Datensätzen, die ab heute erstellt wurden

Verwenden Sie den Bereich mit arel

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

Dann können wir es benutzen

today_posts = Post.created_from_today
Hieu Pham
quelle
where('created_at >= now()')würde nur Elemente finden, bei denen das created_at in der Zukunft war.
PR Whitehead
Ja, ich würde es aus der Antwort entfernen, netter Fang danke
Hieu Pham
Das Problem, das Sie jetzt haben, ist, dass Datensätze, die mit zukünftigen Daten gekennzeichnet sind, ebenso wie die für heute angezeigt werden. Wenn Sie vermeiden möchten, zwischen zu verwenden, sollten Sie dies ebenfalls angeben .lteq(Time.zone.now.end_of_day)).
PR Whitehead
-4

Verwenden Sie in Rails 4.2.3 zum Abrufen der heute mit MySQL erstellten Datensätze Folgendes.

@usergoals = Goal.where ("Benutzer-ID =: Benutzer-ID und Datum (Erstellt_at) =: Datum", {Benutzer-ID: Parameter [: ID], Datum: Datum.Today})

Hier verwende ich mehrere Bedingungen, wenn Sie möchten, können Sie es für eine einzelne Bedingung bearbeiten.

Santu
quelle