web-dev-qa-db-fra.com

Rails date ActiveRecord entre

Je dois interroger les commentaires faits en une journée. Le champ fait partie des horodatages standard, soit created_at. La date sélectionnée provient d'un date_select.

Comment puis-je utiliser ActiveRecord pour le faire?

J'ai besoin de quelque chose comme:

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

Notez simplement que la réponse actuellement acceptée est obsolète dans Rails 3. Faites ceci à la place:

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

Ou, si vous voulez ou devez utiliser conditions de chaîne pures , vous pouvez faire:

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

Personnellement, j’ai créé un espace pour le rendre plus lisible et réutilisable:

Dans comment.rb, vous pouvez définir une étendue:

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

Ensuite, pour créer une requête entre:

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

J'espère que ça aide.

43
Marshall Shen

Ce code devrait fonctionner pour vous:

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

Pour plus d'informations jeter un oeil à calculs de temps

Remarque: Ce code est obsolète . Utilisez le code de la réponse si vous utilisez Rails 3.1/3.2

23
Irukandji

Rails 5.1 a introduit une nouvelle méthode d'assistance de date all_day, voir: https://github.com/Rails/rails/pull/249

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

Si vous utilisez Rails 5.1, la requête ressemblerait à ceci:

Comment.where(created_at: @selected_date.all_day)
21
Bismark

J'ai exécuté ce code pour voir si la réponse cochée fonctionnait, et je devais essayer de permuter les dates pour que tout soit correct. Cela a fonctionné--

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

Si vous pensez que la sortie aurait dû être de 36, considérez ceci, Monsieur, combien de jours 3 jours pour 3 personnes?

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

J'ai utilisé les 3 points au lieu de 2. Trois points vous donne une plage ouverte au début et fermée à la fin. Ainsi, si vous effectuez 2 requêtes pour les plages suivantes, vous ne pouvez pas récupérer la même ligne. tous les deux.

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')
=> #<ActiveRecord::Relation []> 
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')
=> #<ActiveRecord::Relation []> 

Et oui, toujours sympa d'utiliser un oscilloscope!

5
nroose

Il devrait y avoir un comportement d'enregistrement actif par défaut sur ce que je pense. Il est difficile de consulter les dates, en particulier lorsque les fuseaux horaires sont impliqués.

Quoi qu'il en soit, j'utilise:

  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
  }
4
Augustin Riedinger

il y a plusieurs façons. Vous pouvez utiliser cette méthode:

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

Ou ca:

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

Si vous voulez seulement un jour, ce serait plus facile de cette façon:

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

Vous pouvez utiliser gem ci-dessous pour trouver les enregistrements entre les dates,

Ce joyau très facile à utiliser et plus clair Par étoile utilise ce joyau et l’API plus clair et la documentation également bien expliquée.

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

Ici, vous pouvez également passer notre champ Post.by_month("January", field: :updated_at)

Veuillez consulter la documentation et l'essayer.

1
Jenorish