Come ottenere il record creato oggi da rails activerecord?


Risposte:


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

PS: questa risposta è stata modificata in quanto la risposta di Harish Shetty era migliore della mia. Poiché la mia risposta è accettata una. Ho aggiornato questa risposta per il supporto della comunità


4
Si potrebbe fare Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira

1
Non ha senso controllare se qualcosa è stato creato prima della fine di oggi (poiché domani non è ancora successo).
jakeonrails

4
Anche se Post.where("created_at >= ?", Time.zone.now.beginning_of_day)è molto intelligente, lo appoggerei Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). C'è un punto per fare in un modo in cui puoi manipolare il tempo. Ad esempio, se stai testando, probabilmente manipolerai il tempo e quindi la prima opzione non funzionerà. Si desidera evitare quel tipo di possibile guasto futuro che probabilmente richiederà un po 'di tempo per il debug.
lucasarruda

121

So che questa domanda ha una risposta accettata. La soluzione suggerita nella risposta accettata può causare problemi di prestazioni quando la dimensione della tabella aumenta.

In genere, se esegui ricerche in base alla created_atcolonna, aggiungi un indice alla tabella nel file di migrazione.

add_index :posts, :created_at

Ora, per cercare i record creati oggi:

Rotaie 3/4

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

Per cercare i post creati in un giorno specifico.

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

--------- OPPURE -------------

Aggiungi un metodo statico al tuo modello

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

Post.today #returns posts today

Rotaie 2

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

--------- OPPURE -------------

Aggiungi un named_scope al tuo modello

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

Post.today #returns posts today

1
Ottimo punto sull'indicizzazione. Volevo solo chiarire che l' scopeesempio in questo post è solo per Rails 3, poiché sembra che si trovi sotto l'intestazione Rails 2. In Rails 2, dovresti usare named_scopeinvece di scope. Inoltre, in Rails 3, potresti utilizzare in modo equivalente un metodo di classe def self.today where("created_at >= ?", Time.now.beginning_of_day) end che è probabilmente più pulito rispetto all'utilizzo di uno scope in questo caso, poiché ti consente di rinunciare al lambda.
evanrmurphy

@evanrmurphy, grazie per averlo notato. Ho una risposta fissa.
Harish Shetty

@evanrmurphy puoi / dovresti rivedere il tuo commento da "solo Rails 3" a "Rails 3 e versioni successive"?
kaichanvong

@kaichanvong Non ho familiarità con Rails 4, quindi vorrei dire "Rails 3 (e maggiore?)" ma SO non mi permette di modificare il commento: - /
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

La risposta di Mohit Jain adattata per Rails3

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

16

Rails 5.1 ha un all_dayhelper che è utile qui.

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

o

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)

Questo "individua" l'attributo con 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_periodsembra interessante. Non ho trovato alcuna documentazione per questo. Puoi fornire qualche link? In che modo i binari scelgono la colonna per il confronto?
Harish Shetty

1

Per qualche ragione, nessuna delle altre soluzioni in questo post né altre su StackOverflow ha funzionato per me (usando Rails 4.2.4 e Ruby 2.2.3p173). Questa è l'unica query che ho potuto ottenere per lavorare con il mio database Postgres:

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

-1

Per interrogare i record creati da oggi

Usa l'ambito con arel

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

Quindi possiamo usarlo

today_posts = Post.created_from_today

where('created_at >= now()')troverà solo gli elementi in cui created_at era in futuro.
PR Whitehead

Sì, lo rimuoverei dalla risposta, bella cattura, grazie
Hieu Pham

Il problema che hai ora è che i record contrassegnati con date future verranno presentati insieme a quelli di oggi. Se stai cercando di evitare di usare between, dovresti specificare .lteq(Time.zone.now.end_of_day))anche tu .
PR Whitehead

-4

In rails 4.2.3 per ottenere i record creati oggi, utilizzando mysql utilizzare quanto segue.

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

qui sto usando più condizioni se vuoi puoi modificarlo per una singola condizione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.