Como obter o registro criado hoje pelo rails activerecord?


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


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

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

19

Resposta de Mohit Jain adaptada para Rails3

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

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)

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.


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_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'")

-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

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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.