Intrepidd / working_hours

⏰ A modern ruby gem allowing to do time calculation with business / working hours.
https://github.com/Intrepidd/working_hours
MIT License
533 stars 30 forks source link

Global configuration at startup not possible currently #19

Closed oslyak closed 9 years ago

oslyak commented 9 years ago

Tried to create

 /config/initializers/working_hours.rb
module WorkingHours

  WorkingHours::Config.working_hours = {
    mon: {'10:00' => '19:00'},
    tue: {'10:00' => '19:00'},
    wed: {'10:00' => '19:00'},
    thu: {'10:00' => '19:00'},
    fri: {'10:00' => '19:00'},
    sat: {'10:00' => '14:00'}
   }

end

But, this approach to configure Working Hours doesn't works. And I need to include this code in my ActiveRecord model, but I'm not sure that this is good idea.

Tell me please, how to make global Working Hours configuration in Rails?

Intrepidd commented 9 years ago

Hi !

What do you mean by "this approach to configure Working Hours doesn't works" ?

Do you have working hours saved in the database ?

If you have hours saved in the database I'd suggest doing something like that :

class WorkingHour < ActiveRecord::Base

  def with_working_hours(&block)
    WorkingHours::Config.with_config(your_config_from_this_model, &block)
  end

end

and then wrapping your working hours related code :

WorkingHour.first.with_working_hours do
  # your working hour related code 
end
jarthod commented 9 years ago

If you just want to configure working hours globally, just putting this in config/initializers/working_hours.rb should be enough (no need for the module):

WorkingHours::Config.working_hours = {
    mon: {'10:00' => '19:00'},
    tue: {'10:00' => '19:00'},
    wed: {'10:00' => '19:00'},
    thu: {'10:00' => '19:00'},
    fri: {'10:00' => '19:00'},
    sat: {'10:00' => '14:00'}
}

Are you getting errors ? what's the problem ?

oslyak commented 9 years ago

No, I dont have working hours in data base. And yes, just want to configure working hours globally.

I created, without module.

#/config/initializers/working_hours.rb 
  WorkingHours::Config.working_hours = {
    mon: {'10:00' => '19:00'},
    tue: {'10:00' => '19:00'},
    wed: {'10:00' => '19:00'},
    thu: {'10:00' => '19:00'},
    fri: {'10:00' => '19:00'},
    sat: {'10:00' => '14:00'}
  }
SLOG.debug(WorkingHours::Config.working_hours.to_yaml)  # SLOG - my custom logger.

And in boot time I see right values

  :mon:
    '10:00': '19:00'
  :tue:
    '10:00': '19:00'
  :wed:
    '10:00': '19:00'
  :thu:
    '10:00': '19:00'
  :fri:
    '10:00': '19:00'
  :sat:
    '10:00': '14:00'

But then, when I use WorkingHours in my ActiveRecord model.

def expired?
  ...
  SLOG.debug(WorkingHours::Config.working_hours.to_yaml)  # SLOG - my custom logger.
  ...
end

WorkingHours::Config.working_hours. has default values:

  :mon:
    '09:00': '17:00'
  :tue:
    '09:00': '17:00'
  :wed:
    '09:00': '17:00'
  :thu:
    '09:00': '17:00'
  :fri:
    '09:00': '17:00'

So, /config/initializers/working_hours.rb doesn't works for me. And I can't understand where did I go wrong

P.S. rails (4.2.0), ruby 2.2.0p0 (2014-12-25 revision 49005) [x86_64-linux]

jarthod commented 9 years ago

I see, I guess you're using a forking or multithreaded server then ? The config is stored in thread local variable to be threadsafe, so in your case, you'll have to set it either in your server config "after_fork" block or directely in a before_filter (in the controller which need it, or in ApplicationController)

We'll have to improve this because this is very counterintuitive I agree. Let us know if you have any other issue.

Intrepidd commented 9 years ago

Yes, in this case the simpler would be in a before_filter

It's true that this is misleading

oslyak commented 9 years ago

First of all, thank You for your answers. When I use before_action in my controller, everything works perfectly.

But, about threading, I do not use puma or some thing like that, I talking about standart WEBRick in development mode. And I do not use forks and threads in my code.

May be rails 4.2 has something by default, that I missed. Could you take a look at the main configuration files

Gemfile config/application.rb config/environments/development.rb

Intrepidd commented 9 years ago

Webrick is fully multithreaded but I'm not sure rails leverages it.

Main suspect is spring in my opinion.

oslyak commented 9 years ago

I turned off spring in my project, after that created new application on rails 4.2 After that downgrade rails to 4.0.0 and create new test project

In all cases result was the same. At the start values was right. But then using WorkingHours in model:

# /app/models/feedback.rb
class Feedback < ActiveRecord::Base

  def tesh_wh
    puts "Test from model"
    ap WorkingHours::Config.working_hours.to_yaml
  end
end

WorkingHours has default values.

So, in the end my WH init file config/initializers/working_hours.rb

jarthod commented 9 years ago

Thanks for these tests, I guess webrick is just using another thread for processing requests, even if it's sequential. We'll see how to improve this.

jarthod commented 9 years ago

This is now fixed in 1.1.0

Intrepidd commented 9 years ago

:beers: