InesM
InesM

Reputation: 343

ruby on rails - Use method as query column

I what to use a method as a query column on rails.

My model looks like this:

class CourseDate < ActiveRecord::Base
  belongs_to :course, touch: true

  validates :date,  presence: true
  validates :start,  presence: true
  validates :end,  presence: true

  def start_datetime
    DateTime.new(date.year, date.month, date.day, start.hour, start.min, start.sec, start.zone)
  end

end

And what I want to do is something like this:

CourseDate.where("start_datetime > ?", Time.now)

This query is returning: column "start_datetime" does not exist

Is there a way to achieve this?

Upvotes: 0

Views: 373

Answers (3)

Julie
Julie

Reputation: 2011

For the use case you mentioned, you are best off running CourseDate.where start > NOW(). Note that this will use whatever time zone the database server is running in.

Upvotes: 0

Baldrick
Baldrick

Reputation: 24340

PostgreSQL supports date + time (doc), so you could write the query like this :

CourseDate.where('"date" + "start" > ?', Time.now)

Upvotes: 1

Rob
Rob

Reputation: 415

You can't query a ruby method as it doesn't exist in the database.

I would remove the date column and derive the date from the start column.

You could then query start CourseDate.where("start > ?", Time.now) knowing it contains the correct date as well as time.

class CourseDate < ActiveRecord::Base
  belongs_to :course, touch: true

  validates :start,  presence: true
  validates :end,  presence: true
end

An alternative would be to add a datetime column called start_datetime and have a callback that sets its value using the logic you have in your method above before_save:

class CourseDate < ActiveRecord::Base
  belongs_to :course, touch: true

  validates :date,  presence: true
  validates :start,  presence: true
  validates :end,  presence: true

  before_save :set_start_datetime

  private
  def set_start_datetime
    self.start_datetime = DateTime.new(
      date.year,
      date.month,
      date.day,
      start.hour,
      start.min,
      start.sec,
      start.zone
    )
  end
end

CourseDate.where("start_datetime > ?", Time.now) would now work.

Upvotes: 1

Related Questions