Comment créer un enregistrement aujourd'hui par les rails activerecord?


Réponses:


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

PS: Cette réponse a été modifiée car la réponse de Harish Shetty était meilleure que la mienne. Comme ma réponse est acceptée. J'ai mis à jour cette réponse pour le support de la communauté


4
On pourrait faire Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira

1
Il ne sert à rien de vérifier si quelque chose a été créé avant la fin d'aujourd'hui (puisque demain ne s'est pas encore produit).
jakeonrails

4
Bien que ce Post.where("created_at >= ?", Time.zone.now.beginning_of_day)soit très intelligent, je souscris Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Il y a un point à faire de manière à pouvoir manipuler le temps. Par exemple, si vous testez, vous manipulerez probablement le temps et la première option ne fonctionnera pas. Vous voulez éviter ce genre d'échec possible futur qui prendra probablement un certain temps de débogage.
lucasarruda

121

Je sais que cette question a une réponse acceptée. La solution suggérée dans la réponse acceptée peut entraîner des problèmes de performances lorsque la taille de la table augmente.

En règle générale, si vous effectuez des recherches basées sur la created_atcolonne, ajoutez un index sur la table dans votre fichier de migration.

add_index :posts, :created_at

Maintenant, pour rechercher les enregistrements créés aujourd'hui:

Rails 3/4

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

Pour rechercher des articles créés un jour spécifique.

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

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

Ajouter une méthode statique à votre modèle

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 -------------

Ajoutez un named_scope à votre modèle

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

Post.today #returns posts today

1
Excellent point sur l'indexation. Je voulais juste préciser que l' scopeexemple de cet article concerne uniquement Rails 3, car il semble qu'il se trouve sous l'en-tête Rails 2. Dans Rails 2, vous devrez utiliser named_scopeplutôt que scope. De plus, dans Rails 3, vous pouvez utiliser de manière équivalente une méthode de classe def self.today where("created_at >= ?", Time.now.beginning_of_day) end qui est probablement plus propre que d'utiliser une portée dans ce cas, car elle vous permet de renoncer au lambda.
evanrmurphy

@evanrmurphy, merci d'avoir noté cela. J'ai une réponse fixe.
Harish Shetty

@evanrmurphy pouvez / devriez-vous réviser votre commentaire de "Rails 3 uniquement" à "Rails 3 et plus"?
kaichanvong

@kaichanvong Je ne connais pas Rails 4, alors j'aimerais dire "Rails 3 (et plus?)" mais SO ne me laisse pas modifier le commentaire: - /
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 réponse de Mohit Jain adaptée pour Rails3

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

16

Rails 5.1 a une all_dayaide utile ici.

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)

Cette "portée de nom" l'attribut avec le 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, ça a l' between_periodair intéressant. Je n'ai trouvé aucune documentation à ce sujet. Pouvez-vous fournir un lien? Comment les rails choisissent-ils la colonne à comparer?
Harish Shetty

1

Pour une raison quelconque, aucune des autres solutions de cet article ni d'autres sur StackOverflow n'ont fonctionné pour moi (en utilisant Rails 4.2.4 et Ruby 2.2.3p173). C'est la seule requête que je pourrais obtenir pour travailler avec ma base de données Postgres:

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

-1

Pour interroger les enregistrements créés à partir d'aujourd'hui

Utilisez Scope avec Arel

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

Ensuite, nous pouvons l'utiliser

today_posts = Post.created_from_today

where('created_at >= now()')ne trouverait que les éléments où le created_at était dans le futur.
PR Whitehead

Ouais, je le retirerais de la réponse, merci bien
Hieu Pham

Le problème que vous avez maintenant est que les enregistrements qui sont marqués avec des dates futures seraient présentés ainsi que ceux d'aujourd'hui. Si vous essayez d'éviter d'utiliser entre, vous devez également le spécifier .lteq(Time.zone.now.end_of_day)).
PR Whitehead

-4

Dans les rails 4.2.3 pour obtenir les enregistrements créés aujourd'hui, en utilisant mysql, utilisez ce qui suit.

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

ici, j'utilise plusieurs conditions si vous le souhaitez, vous pouvez le modifier pour une seule condition.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.