Tag: Sinatra

State Machine gem and Rails (ActiveModel) 4.1 – NoMethodError – protected method ‘around_validation’ called for StateMachine

State machine is a great gem, unfortunately it's not working with Rails 4.1. If you upgrade your app and try to use it, you'll end up with following error:

NoMethodError - protected method `around_validation' called for #<StateMachine::Machine:0x007fd4ea002c80>:
  activesupport (4.1.4) lib/active_support/callbacks.rb:447:in `public_send'
  activesupport (4.1.4) lib/active_support/callbacks.rb:447:in `block in make_lambda'
  activesupport (4.1.4) lib/active_support/callbacks.rb:298:in `call'
  activesupport (4.1.4) lib/active_support/callbacks.rb:298:in `block in halting'
  activesupport (4.1.4) lib/active_support/callbacks.rb:86:in `call'
  activesupport (4.1.4) lib/active_support/callbacks.rb:86:in `run_callbacks'
  activemodel (4.1.4) lib/active_model/validations/callbacks.rb:111:in `run_validations!'
  activemodel (4.1.4) lib/active_model/validations.rb:317:in `valid?'
  activerecord (4.1.4) lib/active_record/validations.rb:70:in `valid?'
  activerecord (4.1.4) lib/active_record/validations.rb:77:in `perform_validations'
  activerecord (4.1.4) lib/active_record/validations.rb:57:in `save!'
  activerecord (4.1.4) lib/active_record/attribute_methods/dirty.rb:29:in `save!'
  activerecord (4.1.4) lib/active_record/transactions.rb:273:in `block in save!'
  activerecord (4.1.4) lib/active_record/transactions.rb:329:in `block in with_transaction_returning_status'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/database_statements.rb:199:in `transaction'
  activerecord (4.1.4) lib/active_record/transactions.rb:208:in `transaction'
  activerecord (4.1.4) lib/active_record/transactions.rb:326:in `with_transaction_returning_status'
  activerecord (4.1.4) lib/active_record/transactions.rb:273:in `save!'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:487:in `block in save!'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:502:in `block (2 levels) in around_save'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:150:in `block in run_actions'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:170:in `catch_exceptions'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:148:in `run_actions'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:133:in `run_callbacks'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:212:in `run_callbacks'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:63:in `block (2 levels) in perform'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:63:in `catch'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:63:in `block in perform'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:186:in `within_transaction'
  state_machine (1.2.0) lib/state_machine/transition_collection.rb:62:in `perform'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:502:in `block in around_save'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:530:in `block in transaction'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `block in transaction'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/database_statements.rb:209:in `within_new_transaction'
  activerecord (4.1.4) lib/active_record/connection_adapters/abstract/database_statements.rb:201:in `transaction'
  activerecord (4.1.4) lib/active_record/transactions.rb:208:in `transaction'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:529:in `transaction'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:501:in `around_save'
  state_machine (1.2.0) lib/state_machine/integrations/active_record.rb:487:in `save!'
  activerecord (4.1.4) lib/active_record/validations.rb:41:in `create!'
  app/models/concerns/channel/tracked.rb:139:in `find_or_create_channel'
  app/models/concerns/channel/tracked.rb:128:in `track'
  app/controllers/reporting/tracked_channels_controller.rb:20:in `create'
  actionpack (4.1.4) lib/action_controller/metal/implicit_render.rb:4:in `send_action'
  actionpack (4.1.4) lib/abstract_controller/base.rb:189:in `process_action'
  actionpack (4.1.4) lib/action_controller/metal/rendering.rb:10:in `process_action'
  actionpack (4.1.4) lib/abstract_controller/callbacks.rb:20:in `block in process_action'
  activesupport (4.1.4) lib/active_support/callbacks.rb:113:in `call'
  activesupport (4.1.4) lib/active_support/callbacks.rb:113:in `call'

Here's a fix. Just put it into your initializers:

# Stathe machine
module StateMachine
  # Extensions for integrations of state machine
  module Integrations
    # ActiveModel extension that fixes the non-public around_validation error
    module ActiveModel
      send :public, :around_validation
    end
  end
end

Note: It works also for any non-Rails, ActiveModel based apps.

Multiple Sidekiq processes for multiple Rails/Sinatra applications – namespacing

Sidekiq is a great background processing tool that can be used with many applications deployed on the same server. In order to make it work without any issues or collisions, you need to define namespace for each Sidekiq process group within single application. To do so, you need to create an initializer that will contain both: server connection details and a namespace name:

Sidekiq.configure_server do |config|
  config.redis = {
    url: 'redis://localhost:6379',
    namespace: 'my_app_name_production'
  }
end

Sidekiq.configure_client do |config|
  config.redis = {
    url: 'redis://localhost:6379',
    namespace: 'my_app_name_production'
  }
end

Keep in mind, that you need to provide both url and namespace for client and server. I like to hook it up with SettingsLogic gem:

Sidekiq.configure_server do |config|
  config.redis = System::Settings.sidekiq.redis
end

Sidekiq.configure_client do |config|
  config.redis = System::Settings.sidekiq.redis
end

After you deploy all the apps, you can also easily check if everything is working, by simply executing redis console:

$: redis-cli

and running following command:

redis 127.0.0.1:6379> keys *NAMESPACE*

For example:

redis 127.0.0.1:6379> keys *api*
 1) "youtube_api_v2_production:stat:failed:2014-07-04"
 2) "youtube_api_v2_production:MIA-VPS-VM0974:770"
 3) "facebook_api_production:processes"
 4) "facebook_api_production:queues"
 5) "twitter_api_production:MIA-VPS-VM0974:32655"
 6) "youtube_api_v2_production:queues"
 7) "facebook_api_production:stat:processed"
 8) "youtube_api_v2_production:stat:processed:2014-07-04"
 9) "youtube_api_v2_production:stat:processed"
10) "youtube_api_v2_production:processes"
11) "facebook_api_production:MIA-VPS-VM0974:459"
12) "facebook_api_production:stat:processed:2014-07-04"
13) "twitter_api_production:stat:processed:2014-07-04"
14) "twitter_api_production:stat:processed"
15) "twitter_api_production:processes"
16) "twitter_api_production:queues"
17) "youtube_api_v2_production:stat:failed"

Above you can see multiple queues for multiple namespaced apps.

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑