¿Cómo obtener un registro creado hoy por rails activerecord?

Respuestas:

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

PD: Esta respuesta ha sido modificada porque la respuesta de Harish Shetty era mejor que la mía. Como mi respuesta es aceptada una. He actualizado esta respuesta para el apoyo de la comunidad.

Mohit Jain
fuente
4
Se podría hacer Post.where (created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day)
Rafael Oliveira
1
No tiene sentido verificar si algo se creó antes del final de hoy (ya que mañana aún no ha sucedido).
jakeonrails
4
Si bien Post.where("created_at >= ?", Time.zone.now.beginning_of_day)es muy inteligente, lo respaldaría Post.where(created_at: Time.zone.now.beginning_of_day..Time.zone.now.end_of_day). Hay un punto para hacerlo de una manera que pueda manipular el tiempo. Por ejemplo, si está probando, probablemente manipulará el tiempo y luego la primera opción no funcionará. Desea evitar ese tipo de posible falla futura que probablemente llevará algún tiempo de depuración.
lucasarruda
121

Sé que esta pregunta tiene una respuesta aceptada. La solución sugerida en la respuesta aceptada puede causar problemas de rendimiento cuando aumenta el tamaño de la tabla.

Normalmente, si realiza búsquedas basadas en created_atcolumnas, agregue un índice en la tabla en su archivo de migración.

add_index :posts, :created_at

Ahora, para buscar registros creados hoy:

Carriles 3/4

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

Para buscar publicaciones creadas en un día específico.

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

--------- O -------------

Agrega un método estático a tu modelo

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

Post.today #returns posts today

Carriles 2

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

--------- O -------------

Agrega un named_scope a tu 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
fuente
1
Un gran punto sobre la indexación. Solo quería aclarar que el scopeejemplo de esta publicación es solo para Rails 3, ya que parece que está debajo del encabezado Rails 2. En Rails 2, necesitaría usar en named_scopelugar de scope. Además, en Rails 3, podría usar de manera equivalente un método de clase def self.today where("created_at >= ?", Time.now.beginning_of_day) end que probablemente sea más limpio que usar un alcance en este caso, ya que le permite renunciar a la lambda.
evanrmurphy
@evanrmurphy, Gracias por señalar eso. Tengo una respuesta fija.
Harish Shetty
@evanrmurphy, ¿puede / debería revisar su comentario de "Rails 3 solamente" a "Rails 3 y mayores"?
kaichanvong
@kaichanvong No estoy familiarizado con Rails 4, así que me gustaría decir "Rails 3 (¿y mayores?)" pero SO no me deja editar el comentario: - /
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
fuente
19

La respuesta de Mohit Jain adaptada para Rails3

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

Rails 5.1 tiene un all_dayayudante que es útil aquí.

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

o

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

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

Esto "asigna nombres" al atributo con el table_name.

Rafael Oliveira
fuente
5

model.rb

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

posts_controller.rb

Post.posted_today
Parthiv
fuente
2
@Pathiv, between_periodparece interesante. No encontré ninguna documentación para ello. ¿Puede proporcionar algún enlace? ¿Cómo eligen los rieles la columna para comparar?
Harish Shetty
1

Por alguna razón, ninguna de las otras soluciones en esta publicación ni otras en StackOverflow funcionó para mí (usando Rails 4.2.4 y Ruby 2.2.3p173). Esta es la única consulta que pude hacer para trabajar con mi base de datos de Postgres:

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

Para consultar registros creados a partir de hoy

Usar alcance con arel

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

Entonces podemos usarlo

today_posts = Post.created_from_today
Hieu Pham
fuente
where('created_at >= now()')solo encontraría elementos donde created_at estuviera en el futuro.
PR Whitehead
Sí, lo eliminaría de la respuesta, buena captura gracias
Hieu Pham
El problema que tiene ahora es que los registros que están marcados con fechas futuras se presentarían así como los de hoy. Si está tratando de evitar el uso de between, debe especificar .lteq(Time.zone.now.end_of_day))también.
PR Whitehead
-4

En rails 4.2.3 para obtener los registros creados hoy, usando mysql use lo siguiente.

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

aquí estoy usando múltiples condiciones si lo desea, puede editarlo para una sola condición.

santu
fuente