Rails ActiveRecord date between

Eu preciso consultar comentários feitos em um dia. O campo faz parte dos timestamps padrão, é created_at. A data selecionada é proveniente de uma data_select. Como posso usar o ActiveRecord para fazer isso?

Eu preciso de algo como:

"SELECT * FROM comments WHERE created_at BETWEEN '2010-02-03 00:00:00' AND '2010-02-03 23:59:59'" 

Apenas uma nota que a resposta aceita atualmente está obsoleta no Rails 3. Você deve fazer isso em vez disso:

 Comment.where(:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day) 

Ou, se você quiser ou tiver que usar condições de string pura , poderá fazer:

 Comment.where('created_at BETWEEN ? AND ?', @selected_date.beginning_of_day, @selected_date.end_of_day) 

Eu pessoalmente criei um escopo para torná-lo mais legível e reutilizável:

Em você Comment.rb, você pode definir um escopo:

 scope :created_between, lambda {|start_date, end_date| where("created_at >= ? AND created_at < = ?", start_date, end_date )} 

Então, para consultar criado entre:

 @comment.created_between(1.year.ago, Time.now) 

Espero que ajude.

Este código deve funcionar para você:

 Comment.find(:all, :conditions => {:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day}) 

Para mais informações, veja os cálculos do Tempo

Nota: este código está obsoleto . Use o código da resposta se você estiver usando o Rails 3.1 / 3.2

O Rails 5.1 introduziu um novo método auxiliar de data all_day , veja: https://github.com/rails/rails/pull/24930

 >> Date.today.all_day => Wed, 26 Jul 2017 00:00:00 UTC +00:00..Wed, 26 Jul 2017 23:59:59 UTC +00:00 

Se você estiver usando o Rails 5.1, a consulta será semelhante a:

 Comment.where(created_at: @selected_date.all_day) 

Eu corri este código para ver se a resposta marcada funcionava, e tive que tentar trocar as datas para acertar. Isso funcionou …

 Day.where(:reference_date => 3.months.ago..Time.now).count #=> 721 

Se você está pensando que a saída deveria ter sido 36, considere isso, Senhor, quantos dias são 3 dias para 3 pessoas?

 Comment.find(:all, :conditions =>["date(created_at) BETWEEN ? AND ? ", '2011-11-01','2011-11-15']) 

Eu tenho usado os 3 pontos, em vez de 2. Três pontos dão a você um intervalo que é aberto no início e fechado no final, então se você fizer 2 consultas para intervalos subseqüentes, você não pode obter a mesma linha de volta ambos.

 2.2.2 :003 > Comment.where(updated_at: 2.days.ago.beginning_of_day..1.day.ago.beginning_of_day) Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE ("comments"."updated_at" BETWEEN '2015-07-12 00:00:00.000000' AND '2015-07-13 00:00:00.000000') => # 2.2.2 :004 > Comment.where(updated_at: 2.days.ago.beginning_of_day...1.day.ago.beginning_of_day) Comment Load (0.3ms) SELECT "comments".* FROM "comments" WHERE ("comments"."updated_at" >= '2015-07-12 00:00:00.000000' AND "comments"."updated_at" < '2015-07-13 00:00:00.000000') => # 

E, sim, sempre bom usar um escopo!

Se você quer apenas um dia, seria mais fácil assim:

 Comment.all(:conditions => ["date(created_at) = ?", some_date]) 

Deve haver um comportamento de registro ativo padrão neste eu acho. Consultar datas é difícil, especialmente quando estão envolvidos fusos horários.

De qualquer forma, eu uso:

  scope :between, ->(start_date=nil, end_date=nil) { if start_date && end_date where("#{self.table_name}.created_at BETWEEN :start AND :end", start: start_date.beginning_of_day, end: end_date.end_of_day) elsif start_date where("#{self.table_name}.created_at >= ?", start_date.beginning_of_day) elsif end_date where("#{self.table_name}.created_at < = ?", end_date.end_of_day) else all end } 

Existem várias maneiras. Você pode usar este método:

 start = @selected_date.beginning_of_day end = @selected_date.end_of_day @comments = Comment.where("DATE(created_at) BETWEEN ? AND ?", start, end) 

Ou isto:

 @comments = Comment.where(:created_at => @selected_date.beginning_of_day..@selected_date.end_of_day) 

Você poderia usar abaixo gem para encontrar os registros entre as datas,

Esta gem bastante fácil de usar e mais clara Por estrela estou usando esta gem e a API mais clara e documentação também bem explicada.

 Post.between_times(Time.zone.now - 3.hours, # all posts in last 3 hours Time.zone.now) 

Aqui você poderia passar nosso campo também Post.by_month("January", field: :updated_at)

Por favor, veja a documentação e experimente.