3

In "How would you store a business's hours in the db/model of a Rails app", Simon Franzen provided elegant solution (I'm novice programmer, so please mind that it seems like that to me).

And I want to know how to implement is_open? method in model or controller to reflect the "Business is open" or "Business is close" on the view page?

I could not ask him directly because I don't have enough reputation points to comment on his solution.

Code by Simon Franzen

schema:

# migration
class CreateOpeningHours < ActiveRecord::Migration
  def change
    create_table :opening_hours do |t|
      t.integer :entry_id # your model reference
      t.integer :day
      t.time :closes
      t.time :opens
      t.datetime :valid_from
      t.datetime :valid_through
    end
  end
end 

model:

class OpeningHour < ActiveRecord::Base

  belongs_to :entry

  validates_presence_of :day, :closes, :opens, :entry_id
  validates_inclusion_of :day, :in => 1..7
  validate :opens_before_closes 
  validate :valid_from_before_valid_through 

  # sample validation for better user feedback
  validates_uniqueness_of :opens, scope: [:entry_id, :day]
  validates_uniqueness_of :closes, scope: [:entry_id, :day]

  protected
  def opens_before_closes
    errors.add(:closes, I18n.t('errors.opens_before_closes')) if opens && closes && opens >= closes
  end

  def valid_from_before_valid_through
    errors.add(:valid_through, I18n.t('errors.valid_from_before_valid_through')) if valid_from && valid_through && valid_from >= valid_through
  end

end
Community
  • 1
  • 1
d_dnara
  • 49
  • 1
  • 5
  • 1
    @Iceman. It's very shame but I did not try to solve this. I could only code something from tutorial. But I also realized that best way to learn is making your original. From next time, I try first and ask the question on this post for better solution. – d_dnara Feb 17 '17 at 15:25

2 Answers2

2

Given there is a model Business exists which has_many :opening_hours then open? (in ruby we do not need obsolete is_ prefix as we can define methods with ? in the end to indicate that it returns boolean value) method can be implemented as follows:

class Business < ActiveRecord::Base
  has_many :opening_hours

  # ...

  def open?
    opening_hours.where("? BETWEEN opens AND closes", Time.zone.now).any?
  end

  # ...

end
Slava.K
  • 3,073
  • 3
  • 17
  • 28
  • 2
    or db agnostic `opening_hours.where("? BETWEEN opens AND closes", Time.zone.now).any?` – Eyeslandic Feb 15 '17 at 09:39
  • @Slava.K thank you very much for your answer. I wanted to vote your answer but I could not because of my low score on my reputation. – d_dnara Feb 17 '17 at 15:30
  • @Iceman Thank you. I don't have any clue about what make this db agnostic but this is very good example for me. – d_dnara Feb 17 '17 at 15:36
  • @Daiji Db agnostic means it doesn't use any special commands or operators that are only found in e.g. postgres but not in mysql. – Eyeslandic Feb 17 '17 at 16:08
  • @Iceman I really appreciate your teachings. I should read documentation on postgres and mysql since I choose rails as my preferred framework than php. If you know any way that I can compliment you, please kindly suggest me. – d_dnara Feb 17 '17 at 16:41
0

You can try to add the day also into it to check whether today the business is opened or not?

def open?
   opening_hours.where(day: Time.zone.now.wday).where('? BETWEEN opens AND closes', Time.zone.now).any?
end