Michael L.
Michael L.

Reputation: 272

How to check if associated model has entries in Rails 5?

I have a model RegularOpeningHour(dayOfWeek: integer) that is associated to a model OpeningTime(opens: time, closes: time). RegularOpeningHour has an 1:n relation to OpeningTime, so that a specific day can have many opening times.

(I know that I simply could have one entry with 'opens' and 'closes' included in RegularOpeningHour but for other reasons I need this splitting)

Now I want a open?-Method, that returns whether the business is opened or not. I tried the following in my model file regular_opening_hour.rb:

def open?
    RegularOpeningHour.where(dayOfWeek: Time.zone.now.wday).any? { |opening_hour| opening_hour.opening_times.where('? BETWEEN opens AND closes', Time.zone.now).any? }
end

Unforutnately, that doesn't work. Any ideas to solve this?

Upvotes: 1

Views: 99

Answers (3)

Krupa Suthar
Krupa Suthar

Reputation: 680

Since you have has_many association of RegularOpeningHour to OpeningTime you can use join query like below.:

RegularOpeningHour.joins(:opening_times).where(dayOfWeek: Time.zone.now.wday).where('? BETWEEN opening_times.opens AND opening_times.closes', Time.zone.now).any?

Upvotes: 1

3limin4t0r
3limin4t0r

Reputation: 21130

You could create some scopes to make selecting open OpeningTimes and open RegularOpeningHours less clunky. This makes creating the given selection much easier.

class OpeningTime < ApplicationRecord

  # ...

  belongs_to :regular_opening_hour

  def self.open
    time = Time.current
    where(arel_table[:opens].lteq(time).and(arel_table[:closes].gteq(time)))
  end

  # ...

end

class RegularOpeningHour < ApplicationRecord

  # ...

  has_many :opening_times

  def self.open
    where(
      dayOfWeek: Time.current.wday,
      id: OpeningTime.select(:regular_opening_hour_id).open,
    )
  end

  # ...

end

def open?
  RegularOpeningHour.open.any?
end

Upvotes: 1

1Rhino
1Rhino

Reputation: 298

How about this:

def open?
  joins(:opening_times)
    .where(dayOfWeek: Time.current.wday)
    .where("opens <= :time AND closes >= :time", time: Time.current)
    .any?
end

EDIT: Missing ':' in the join

Upvotes: 2

Related Questions