Como obter o registro criado hoje pelo rails activerecord?

113

Como devo escrever a declaração condicional para quando desejo obter todos os registros que foram criados hoje?

Victor Lam
fonte

Respostas:

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

PS: Esta resposta foi modificada porque a resposta de Harish Shetty era melhor do que a minha. Como minha resposta é aceita. Eu atualizei esta resposta para o suporte da comunidade

Mohit Jain
fonte
4
Pode-se fazer Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira
1
Não adianta verificar se algo foi criado antes do final de hoje (já que o amanhã ainda não aconteceu).
jakeonrails
4
Embora Post.where("created_at >= ?", Time.zone.now.beginning_of_day)seja muito inteligente, eu endossaria Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Há um ponto em fazer de uma forma que você possa manipular o tempo. Por exemplo, se você estiver testando, provavelmente irá manipular o tempo e então a primeira opção não funcionará. Você deseja evitar esse tipo de possível falha futura que provavelmente levará algum tempo de depuração.
lucasarruda
123

Eu sei que esta pergunta tem uma resposta aceita. A solução sugerida na resposta aceita pode causar problemas de desempenho quando o tamanho da mesa aumenta.

Normalmente, se você realizar pesquisas com base na created_atcoluna, adicione um índice na tabela em seu arquivo de migração.

add_index :posts, :created_at

Agora, para consultar os registros criados hoje:

Rails 3/4

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

Para pesquisar postagens criadas em um dia específico.

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

--------- OU -------------

Adicione um método estático ao seu modelo

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

Post.today #returns posts today

Rails 2

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

--------- OU -------------

Adicione um named_scope ao seu modelo

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
fonte
1
Excelente ponto sobre indexação. Só queria esclarecer que o scopeexemplo neste post é apenas para Rails 3, já que parece que está sob o título Rails 2. No Rails 2, você precisaria usar named_scopeao invés de scope. Além disso, no Rails 3, você poderia usar de forma equivalente um método de classe def self.today where("created_at >= ?", Time.now.beginning_of_day) end que provavelmente é mais limpo do que usar um escopo neste caso, já que permite que você renuncie ao lambda.
evanrmurphy
@evanrmurphy, Obrigado por notar isso. Eu fixei a resposta.
Harish Shetty
@evanrmurphy você pode / deve revisar seu comentário de "Apenas Rails 3" para "Rails 3 e superior"?
Kaichanvong
@kaichanvong Não estou familiarizado com Rails 4, então gostaria de dizer "Rails 3 (e superior?)", mas SO não me deixa editar o comentário: - /
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
fonte
19

Resposta de Mohit Jain adaptada para Rails3

Model.where "DATE(created_at) = DATE(?)", Time.now
o tipo de mim
fonte
16

O Rails 5.1 tem um all_dayhelper que é útil aqui.

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

ou

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

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

Isso "namescope" o atributo com o table_name.

Rafael Oliveira
fonte
5

model.rb

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

posts_controller.rb

Post.posted_today
Parthiv
fonte
2
@Pathiv, between_periodparece interessante. Não encontrei nenhuma documentação para isso. Você pode fornecer algum link? Como o Rails escolhe a coluna para comparação?
Harish Shetty
1

Por alguma razão, nenhuma das outras soluções neste post nem em outras no StackOverflow funcionou para mim (usando Rails 4.2.4 e Ruby 2.2.3p173). Esta é a única consulta que consegui fazer com meu banco de dados Postgres:

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

Para consultar os registros criados a partir de hoje

Use o escopo com arel

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

Então podemos usá-lo

today_posts = Post.created_from_today
Hieu Pham
fonte
where('created_at >= now()')só encontraria itens onde created_at estivesse no futuro.
PR Whitehead
Sim, eu o removeria da resposta, boa captura, obrigado
Hieu Pham
O problema que você tem agora é que os registros marcados com datas futuras seriam apresentados, bem como os de hoje. Se você está tentando evitar o uso de entre, também deve especificar .lteq(Time.zone.now.end_of_day)).
PR Whitehead
-4

No rails 4.2.3, para obter os registros criados hoje, usando o mysql use o seguinte.

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

aqui estou usando várias condições, se você quiser, pode editá-lo para uma única condição.

santu
fonte