0

You have a model Store with an attribute time_zone(New York, London, Tokyo, etc.).

All stores are open from 8am to 9pm in their local time zone.

You have an instance method to check if the store is currently open:

def currently_open?
  current_store_time = Time.now.in_time_zone(time_zone)
  (8...21).cover? current_store_time.hour
end

How do you create a rails scope for all currently open stores using the Store#currently_open? instance method (or without that method, but I want to use the rails scope syntax).

scope :currently_open, -> { "use Store#currently_open? here" }

4
  • heading seems like -> Rails class method using instance method. I guess you misunderstood basics. Commented Mar 2, 2020 at 9:11
  • What's the data type of time_zone, what RDMBS are you using (if any)? Commented Mar 2, 2020 at 9:46
  • 1
    BTW, (8..21).cover? current_store_time will always return false. You have to compare against current_store_time.hour and you probably want 8...21 (triple dot), i.e. up to but not including 21. (unless the stores are open until 9:59pm) Commented Mar 3, 2020 at 12:17
  • You are right! Thanks Stefan Commented Mar 4, 2020 at 15:09

2 Answers 2

3

Does this works for you?

scope :with_current_store_time, -> {
  select(all.arel.projections, "date_part('hour', NOW() at time zone time_zone) as current_store_time")
}
scope :currently_open, -> {
  with_current_store_time.where(current_store_time: 8..21)
}

Basically I rewrote current_store_time as a scope (with_current_store_time)

I answered this using these as references:

Notes :

  1. current_store_time probably not describing the actual value being calculated.

  2. current_store_time is returning hour, on the specified timezone.

Sign up to request clarification or add additional context in comments.

Comments

1

If your table only contains a time_zone string which contains a valid Rails time zone name (or alias), you'll have to somehow generate a list of time zone names that are currently between 8 am and 9 pm.

To do so, you could write a helper method that fetches the used time zones in your table via Store.distinct.pluck(:time_zone) and selects those that match the criteria:

class Store
  def self.time_zones_between(hours)
    distinct.pluck(:time_zone).select do |time_zone|
      Time.use_zone(time_zone) { hours.cover?(Time.current.hour) }
    end
  end

  scope :currently_open, -> { where(time_zone: time_zones_between(8...21) }
end

Note that calling Store.currently_open will result two queries: one to get the time zones and one to fetch the actual results. You can avoid the first query by providing the list of available time zones yourself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.