Code Monkey home page Code Monkey logo

rails-observers's Introduction

Build Status

Rails::Observers

Rails Observers (removed from core in Rails 4.0)

Installation

Add this line to your application's Gemfile:

gem 'rails-observers'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rails-observers

Usage

This gem contains two observers:

  • Active Record Observer
  • Action Controller Sweeper

Active Record Observer

Observer classes respond to life cycle callbacks to implement trigger-like behavior outside the original class. This is a great way to reduce the clutter that normally comes when the model class is burdened with functionality that doesn't pertain to the core responsibility of the class. Observers are put in app/models (e.g. app/models/comment_observer.rb). Example:

class CommentObserver < ActiveRecord::Observer
  def after_save(comment)
    Notifications.comment("[email protected]", "New comment was posted", comment).deliver
  end
end

This Observer sends an email when a Comment#save is finished.

class ContactObserver < ActiveRecord::Observer
  def after_create(contact)
    contact.logger.info('New contact added!')
  end

  def after_destroy(contact)
    contact.logger.warn("Contact with an id of #{contact.id} was destroyed!")
  end
end

This Observer uses logger to log when specific callbacks are triggered.

The convention is to name observers after the class they observe. If you absolutely need to override this, or want to use one observer for several classes, use observe:

class NotificationsObserver < ActiveRecord::Observer
  observe :comment, :like

  def after_create(record)
    # notifiy users of new comment or like
  end

end

Please note that observers are called in the order that they are defined. This means that callbacks in an observer will always be called after callbacks defined in the model itself. Likewise, has_one and has_many use callbacks to enforce dependent: :destroy. Therefore, associated records will be destroyed before the observer's before_destroy is called.

For an observer to be active, it must be registered first. This can be done by adding the following line into the application.rb:

    config.active_record.observers = :contact_observer

Enable multiple observers using array:

    config.active_record.observers = [:contact_observer, :user_observer]

Observers can also be registered on an environment-specific basis by simply using the corresponding environment's configuration file instead of application.rb.

Action Controller Sweeper

Sweepers are the terminators of the caching world and responsible for expiring caches when model objects change. They do this by being half-observers, half-filters and implementing callbacks for both roles. A Sweeper example:

class ListSweeper < ActionController::Caching::Sweeper
  observe List, Item

  def after_save(record)
    list = record.is_a?(List) ? record : record.list
    expire_page(controller: "lists", action: %w( show public feed ), id: list.id)
    expire_action(controller: "lists", action: "all")
    list.shares.each { |share| expire_page(controller: "lists", action: "show", id: share.url_key) }
  end
end

The sweeper is assigned in the controllers that wish to have its job performed using the cache_sweeper class method:

class ListsController < ApplicationController
  caches_action :index, :show, :public, :feed
  cache_sweeper :list_sweeper, only: [ :edit, :destroy, :share ]
end

In the example above, four actions are cached and three actions are responsible for expiring those caches.

You can also name an explicit class in the declaration of a sweeper, which is needed if the sweeper is in a module:

class ListsController < ApplicationController
  caches_action :index, :show, :public, :feed
  cache_sweeper OpenBar::Sweeper, only: [ :edit, :destroy, :share ]
end

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

rails-observers's People

Contributors

amatsuda avatar artfuldodger avatar brchristian avatar camelmasa avatar carlosantoniodasilva avatar cprodhomme avatar davidcelis avatar dhh avatar earnold avatar guilleiguaran avatar haseeb-qureshi avatar jeremy avatar jeroenvisser101 avatar jesenko avatar kaspth avatar mvastola avatar rafaelfranca avatar robertomiranda avatar steveklabnik avatar sudhirj avatar tejasbubane avatar tiegz avatar voxik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rails-observers's Issues

sweepers never trigger model callbacks

This is on rails 3.2.16

I have the following controller:

   `class VehicleController < ApplicationController
        cache_sweeper :vehicle_sweeper

        def update
            @vehicle.assign_attributes(params[:vehicle])
            @vehicle.save
         end
    end`


The following sweeper:

     `class VehicleSweeper < ActionController::Caching::Sweeper
           observe Vehicle

           def intialize
                puts "foo I'm in the sweeper"
           end

            def before_save(vehicle)
                 puts "why am I not getting called?"
            end
       end`

The sweeper loads (the initialize is triggered), but the before_save never is.

What could be causing this?

undefined method add_observer when using Observer for Mailer from Rails Engine

I keep getting this error when I start a Rails 4.2.4 application consuming a Rails Engine with a Mailer Observer configured.

Details are below with some code information replaced with placeholders to protect my client's code rights.

engine.rb configuration:

config.autoload_paths += %W(#{config.root}/app/observers)
config.active_record.observers = 'NameOfModule::NameOfObserver'

observer code:

module NameOfModule
  class NameOfObserver < ActiveRecord::Observer
    observe 'NameOfModule::NameOfMailer'
    ...

Error:

$ rails s
=> Booting Thin
=> Rails 4.2.4 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server
Exiting
/Users/User/.rvm/gems/ruby-2.3.0@code/gems/attr_encrypted-1.3.5/lib/attr_encrypted.rb:259:in `method_missing': undefined method `add_observer' for Buccaneer::EntryMailer:Class (NoMethodError)
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/actionmailer-4.2.4/lib/action_mailer/base.rb:569:in `method_missing'
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/rails-observers-0.1.2/lib/rails/observers/active_model/observing.rb:364:in `add_observer!'
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/rails-observers-0.1.2/lib/rails/observers/activerecord/observer.rb:105:in `add_observer!'
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/rails-observers-0.1.2/lib/rails/observers/active_model/observing.rb:341:in `block in initialize'
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/rails-observers-0.1.2/lib/rails/observers/active_model/observing.rb:341:in `each'
    from /Users/User/.rvm/gems/ruby-2.3.0@code/gems/rails-observers-0.1.2/lib/rails/observers/active_model/observing.rb:341:in `initialize'

I will add any further details if I discover any.

Undefined method `cache_sweeper' or uninitialized constant ActionController::Caching::Sweeper

I use cache sweepers in my project and try to make it work on Rails 4 master. I have added gem 'rails-observers', updated bundle. But I am still getting error undefined methodcache_sweeper' for ObservationsController:Class (NoMethodError)`.

I tried to debug and saw that rails-observers are actually loaded, but unfortunately I failed to go deeper into that eager_autoload stuff.

If I try to require my sweeper on top of controller I got error there: uninitialized constant ActionController::Caching::Sweeper. So it seems the values are not properly autoloaded

I tried both v 1.1.0 and edge version of the gem.

`config.active_record.observers` syntax broken in Rails 5?

Trying to add an observer with the standard config.active_record.observers = [:user_observer] syntax in application.rb. But nothing ever triggers.

I was able to get them to trigger by adding an initializer with this syntax instead:

ActiveRecord::Base.add_observer UserObserver.instance

Any Rails members know of changes in Rails 5 that would have broken that config syntax?

Compatibility with Rails 5.0

With the release of Rails 5.0.0.beta1 just days ago, many users (myself included) are seeking to upgrade their current Rails 4.2 apps to ensure forward-compatibility with this new version of Rails and to make use of its new features and capabilities.

rails-observers version 0.1.3.alpha is forward-compatible with Rails 5, but it has not been pushed to RubyGems, largely preventing usage of this gem (or even experimentation with it) in this new version of Rails as the latest released version of rails-observers (0.1.2) is locked to the Rails 4.x series.

I would like to request that a new version of rails-observers be pushed to RubyGems to mark the beginning of Rails 5 compatibility. (Ideally as a release, rather than an alpha version, but anything would be an improvement.)

Can't disable observers

I'm going mad.

In most of my Rspec specs I want observers to be disabled, except for some. But

 ActiveRecord::Base.observers.disable :all

is not working.

It goes through the motions, something happens, I can see all the observers in the disabled_observers array but the observers still trigger.

It's driving me nuts. However I can see that the gem tests for disable are passing. It must be that the tests are not testing real things

Observers are empty and cannot disable (version 0.1.5)

Hi all,

I need to make call while disabling one of the observers, but there is something I have noticed. Due to some sensitive information, I'll replace the names of classes. For the purpose of this issue, I am using Rails 4.2.11 and rails-observer 0.1.5.

I've tried all of these on the rails console:

  • ActiveRecord::Base.observers returns all of the observers I have defined in config.active_record.observers.
  • Foo.observers returns an empty array, even though I do have FooObserver and it's in config.active_record.observers. I even checked to make sure ActiveRecord::Base.observers has foo_observer which appears to be the case.
  • So I then tried to disable by calling ActiveRecord::Base.observers.disable :foo_observer, but got the following output:
=> [PgSearch::Document(Table doesn't exist),
 ApplicationRecord(abstract),
 ... the rest may be irrelevant, since it's all model definitions. Interestingly enough, I don't see the model Foo in the list, even though it does exist and I can invoke it...
 ]

I hope this is enough information and hope someone has a good solution on how I can get around it.

Gem not working with Rails 5

When upgrading to Rails 5, bundler works for all my other gems - but when I add rails-observers, this is the error I get:

bundle update
Fetching gem metadata from https://rubygems.org/.........
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies........................................................................................................................................................................................................................................................................................................................................................................................................................
Bundler could not find compatible versions for gem "rack":
  In Gemfile:
    rails (= 5.0.0.beta3) ruby depends on
      actioncable (= 5.0.0.beta3) ruby depends on
        actionpack (= 5.0.0.beta3) ruby depends on
          rack (~> 2.x) ruby

    rails (= 5.0.0.beta3) ruby depends on
      actioncable (= 5.0.0.beta3) ruby depends on
        actionpack (= 5.0.0.beta3) ruby depends on
          rack-test (~> 0.6.3) ruby depends on
            rack (>= 1.0) ruby

    sass-rails (>= 0) ruby depends on
      sprockets (< 4.0, >= 2.8) ruby depends on
        rack (< 3, > 1) ruby

    capybara (>= 0) ruby depends on
      rack (>= 1.0.0) ruby

    passenger (>= 0) ruby depends on
      rack (>= 0) ruby

    thin (>= 0) ruby depends on
      rack (~> 1.0) ruby
Bundler could not find compatible versions for gem "activemodel":
  In Gemfile:
    rails (= 5.0.0.beta3) ruby depends on
      activemodel (= 5.0.0.beta3) ruby

    rails (= 5.0.0.beta3) ruby depends on
      activemodel (= 5.0.0.beta3) ruby

    web-console (>= 0) ruby depends on
      activemodel (>= 4.2) ruby

    simple_form (>= 0) ruby depends on
      activemodel (< 5.1, > 4) ruby

    carrierwave (>= 0) ruby depends on
      activemodel (>= 3.2.0) ruby

    rails-observers (>= 0) ruby depends on
      activemodel (~> 4.0) ruby
Bundler could not find compatible versions for gem "railties":
  In Gemfile:
    rails (= 5.0.0.beta3) ruby depends on
      railties (= 5.0.0.beta3) ruby

    lograge (~> 0.3.1) ruby depends on
      railties (>= 3) ruby

    coffee-rails (>= 0) ruby depends on
      railties (< 5.1.x, >= 4.0.0) ruby

    sass-rails (>= 0) ruby depends on
      railties (< 5.0, >= 4.0.0) ruby

    jquery-turbolinks (>= 0) ruby depends on
      railties (>= 3.1.0) ruby

    factory_girl_rails (>= 0) ruby depends on
      railties (>= 3.0.0) ruby

    web-console (>= 0) ruby depends on
      railties (>= 4.2) ruby

    jquery-rails (>= 0) ruby depends on
      railties (>= 4.2.0) ruby

    rails-observers (>= 0) ruby depends on
      railties (~> 4.0.0.beta) ruby

License missing from gemspec

Some companies will only use gems with a certain license.
The canonical and easy way to check is via the gemspec,

via e.g.

spec.license = 'MIT'
# or
spec.licenses = ['MIT', 'GPL-2']

Even for projects that already specify a license, including a license in your gemspec is a good practice, since it is easily
discoverable there without having to check the readme or for a license file.

For example, there is a License Finder gem to help companies ensure all gems they use
meet their licensing needs. This tool depends on license information being available in the gemspec. This is an important enough
issue that even Bundler now generates gems with a default 'MIT' license.

If you need help choosing a license (sorry, I haven't checked your readme or looked for a license file),
github has created a license picker tool.

In case you're wondering how I found you and why I made this issue, it's because I'm collecting stats on gems (I was originally
looking for download data) and decided to collect license metadata,too, and make issues for gemspecs not specifying a license as a public service :).

I hope you'll consider specifying a license in your gemspec. If not, please just close the issue and let me know. In either case, I'll follow up. Thanks!

p.s. I've written a blog post about this project

The Rails app gets loading during migrations with registered observers.

Steps to reproduce

I've created an example app here. It has a User model and a pending migration. The user model will raise when loaded.

So the following happens:

% rake db:migrate
rake aborted!
application loaded too early
/Users/kelly/git/example_app/app/models/user.rb:2:in `<class:User>'
...

Expected behavior

It was my understanding that an app shouldn't be loaded during migrations, and the app our company uses has many cases where it makes that assumption.

System configuration

% rails --version
Rails 4.2.1
% ruby --version
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

Failing test with 0.1.2

Hi,

i am getting one failure during the test suite with 0.1.2 version:

1) Failure:
ObserverTest#test_tracks_implicit_observable_models [/builddir/build/BUILD/rails-observers-0.1.2/usr/share/gems/gems/rails-observers-0.1.2/test/observing_test.rb:118]:
Expected: [Foo]
  Actual: [Foo, #<Class:0x00000005389d48>]

It's this test:

test "tracks implicit observable models" do
    instance = FooObserver.new
    assert_equal [Foo], instance.observed_classes
end

And I am unsure whether it should be failing (and fixed). It makes sense to me that the instance class is included.

The only changed I had to done was to switch to active_support/test_case which is already used in master. Here are the dependencies used during build:

DEBUG util.py:281:  Installed:
DEBUG util.py:281:    ruby.x86_64 0:2.1.2-23.fc21             ruby-libs.x86_64 0:2.1.2-23.fc21      
DEBUG util.py:281:    rubygem-minitest.noarch 0:5.3.1-2.fc21  rubygem-mocha.noarch 0:0.14.0-1.fc20  
DEBUG util.py:281:    rubygem-rails.noarch 1:4.1.4-1.fc21     rubygem-sqlite3.x86_64 0:1.3.8-2.fc21 
DEBUG util.py:281:    rubygems-devel.noarch 0:2.2.2-101.fc21 
DEBUG util.py:281:  Dependency Installed:
DEBUG util.py:281:    libyaml.x86_64 0:0.1.6-3.fc21                                                 
DEBUG util.py:281:    ruby-irb.noarch 0:2.1.2-23.fc21                                               
DEBUG util.py:281:    rubygem-actionmailer.noarch 1:4.1.4-1.fc21                                    
DEBUG util.py:281:    rubygem-actionpack.noarch 1:4.1.4-1.fc21                                      
DEBUG util.py:281:    rubygem-actionview.noarch 0:4.1.4-1.fc21                                      
DEBUG util.py:281:    rubygem-activemodel.noarch 0:4.1.4-1.fc21                                     
DEBUG util.py:281:    rubygem-activerecord.noarch 1:4.1.4-1.fc21                                    
DEBUG util.py:281:    rubygem-activesupport.noarch 1:4.1.4-1.fc21                                   
DEBUG util.py:281:    rubygem-arel.noarch 0:5.0.0-2.fc21                                            
DEBUG util.py:281:    rubygem-bigdecimal.x86_64 0:1.2.4-23.fc21                                     
DEBUG util.py:281:    rubygem-builder.noarch 0:3.2.2-2.fc21                                         
DEBUG util.py:281:    rubygem-bundler.noarch 0:1.5.2-2.fc21                                         
DEBUG util.py:281:    rubygem-erubis.noarch 0:2.7.0-7.fc21                                          
DEBUG util.py:281:    rubygem-hike.noarch 0:1.2.3-1.fc21                                            
DEBUG util.py:281:    rubygem-i18n.noarch 0:0.6.9-4.fc21                                            
DEBUG util.py:281:    rubygem-io-console.x86_64 0:0.4.2-23.fc21                                     
DEBUG util.py:281:    rubygem-json.x86_64 0:1.8.1-23.fc21                                           
DEBUG util.py:281:    rubygem-mail.noarch 0:2.5.4-2.fc21                                            
DEBUG util.py:281:    rubygem-metaclass.noarch 0:0.0.4-1.fc21                                       
DEBUG util.py:281:    rubygem-mime-types.noarch 0:1.25.1-1.fc21                                     
DEBUG util.py:281:    rubygem-multi_json.noarch 0:1.8.4-2.fc21                                      
DEBUG util.py:281:    rubygem-net-http-persistent.noarch 0:2.9.4-3.fc21                             
DEBUG util.py:281:    rubygem-polyglot.noarch 0:0.3.4-2.fc21                                        
DEBUG util.py:281:    rubygem-psych.x86_64 0:2.0.5-23.fc21                                          
DEBUG util.py:281:    rubygem-rack.noarch 1:1.5.2-3.fc21                                            
DEBUG util.py:281:    rubygem-rack-test.noarch 0:0.6.2-5.fc21                                       
DEBUG util.py:281:    rubygem-railties.noarch 0:4.1.4-1.fc21                                        
DEBUG util.py:281:    rubygem-rake.noarch 0:10.1.0-23.fc21                                          
DEBUG util.py:281:    rubygem-rdoc.noarch 0:4.1.0-23.fc21                                           
DEBUG util.py:281:    rubygem-sprockets.noarch 0:2.12.1-2.fc21                                      
DEBUG util.py:281:    rubygem-sprockets-rails.noarch 0:2.1.3-1.fc21                                 
DEBUG util.py:281:    rubygem-thor.noarch 0:0.18.1-2.fc21                                           
DEBUG util.py:281:    rubygem-thread_safe.noarch 0:0.3.3-2.fc21                                     
DEBUG util.py:281:    rubygem-tilt.noarch 0:1.4.1-1.fc21                                            
DEBUG util.py:281:    rubygem-treetop.noarch 0:1.4.14-2.fc21                                        
DEBUG util.py:281:    rubygem-tzinfo.noarch 0:1.1.0-3.fc21                                          
DEBUG util.py:281:    rubygems.noarch 0:2.2.2-101.fc21                                              
DEBUG util.py:281:    rubypick.noarch 0:1.1.1-2.fc21    

Observers not firing when running a single Rails 4 test

I'm in the process of upgrading out Rails 3.2 app to Rails 4.1.5. When I run the full test suite (rake test) teh observer callbacks are fired. However, when I try to run a single test (rake test TEST=somefile.rb) the observer callbacks are not fire.

Any idea why this would be? I do not see the same behavior in Rails 3.2

Usage information...

Hi Guys,

I'm looking for some opinions on the following points. It's a good candidate for the mailing list but the issue tracker will likely be the first destination for anyone upgrading to AR4 and having similar questions about Observers.

  1. I used to use ActiveRecord and Observers outside of Rails. I required them like so:
require 'active_record' unless defined? Rails

If I pull in this library, Rails is defined, which annoyingly was my default check to see if my code was in a Rails environment. What is the best practice for using this outside of Rails, and is there a new default for checking if we are within a Rails environment?

  1. The old argument of inclusion in Rails Core? According to RubyGems...
    Rails version 4 has been downloaded 60,884 times
    Rails-Observers (this version) has been downloaded 12,699 times
    I'd say that was a fair proportion of apps using Observers? If underuse was the primary reason for removal, i'd argue the stats disagree.. Until seeing those numbers I agreed with the decision to drop from core.

  2. I was using the following Observer before this change.. Is it a good enough use case/Rails best practice that you'd recommend me fixing my point 1 above and continuing or utilising another pattern?

class PublishObserver < ActiveRecord::Observer
  observe :camera, :camera_image, :image, :image_request

  def after_create(record)
    publish_action(:create, record)
  end

  def after_update(record)
    publish_action(:update, record)
  end

  def after_destroy(record)
    publish_action(:destroy, record)
  end


  private
    def publish_action( action, record )
      name = record.class.name.downcase.gsub(' ', '')

      case action
        when :create || :update
          entity_module = ::Deckchair::CacheStore.model_name_to_module( name )
          entity_module.add( record.attributes )
        when :destroy
          entity_module = ::Deckchair::CacheStore.model_name_to_module( name )
          entity_module.destroy( record.attributes )
        else
          return false
      end

    end

end

Regards,

Gareth

Observers not reloading in development

When I use a tool like spring to keep my rails app loaded, observers are not reloaded like models are. In order to see any changes to observers, I must stop spring and reload my rails app.

When using ActiveModel only (not ActiveRecord) ActiveModel::Observing is not defined.

Hi,

When using ActiveModel only (not ActiveRecord), ActiveModel::Observing and ActiveModel::Observer are not defined because 'rails/observers/active_model/active_model' is not required in Railtie.

As a workaround, I can
require 'rails/observers/active_model/active_model'
before using ActiveModel::Observing, but I think it should be put somewhere in the Railtie.

Broken in rails engine testing environment

I am unable to use rails-observers in the Dummy app provided by rails. I keep getting:

undefined method observers=' for ActiveRecord::Base:Class (NoMethodError)`

version info:

ruby 2.6.2p47 (2019-03-13 revision 67232) [i686-linux]
Rails 5.2.3

Steps to reproduce:

  1. Create a plugin

rails plugin new blorgh --mountable

  1. Edit blorgh.gemspec and add 'rails-observers' as a dependency
$:.push File.expand_path("lib", __dir__)
require "blorgh/version"
Gem::Specification.new do |spec|
  spec.name        = "blorgh"
  spec.version     = Blorgh::VERSION
  spec.authors     = ["Stone Tickle"]
  spec.email       = ["[email protected]"]
  spec.summary     = "Summary of Blorgh."
  spec.license     = "MIT"

  spec.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]

  spec.add_dependency "rails", "~> 5.2.3"
  spec.add_dependency "rails-observers"

  spec.add_development_dependency "sqlite3"
end
  1. edit test/dummy/config/application.rb and add an observer
require_relative 'boot'

require 'rails/all'

Bundler.require(*Rails.groups)
require "blorgh"

module Dummy
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 5.2

    # Settings in config/environments/* take precedence over those specified here.
    # Application configuration can go into files in config/initializers
    # -- all .rb files in that directory are automatically loaded after loading
    # the framework and any gems in your application.
    config.active_record.observers = %i[test_observer]
  end
  1. run bin/rails t
Traceback (most recent call last):
        41: from bin/rails:14:in `<main>'
        40: from bin/rails:14:in `require'
        39: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/engine/commands.rb:9:in `<top (required)>'
        38: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/engine/commands.rb:9:in `require'
        37: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/commands.rb:18:in `<top (required)>'
        36: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/command.rb:46:in `invoke'
        35: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/command/base.rb:65:in `perform'
        34: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/thor-0.20.0/lib/thor.rb:387:in `dispatch'
        33: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/thor-0.20.0/lib/thor/invocation.rb:126:in `invoke_command'
        32: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/thor-0.20.0/lib/thor/command.rb:27:in `run'
        31: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/commands/test/test_command.rb:33:in `perform'
        30: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_unit/runner.rb:39:in `run'
        29: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_unit/runner.rb:50:in `load_tests'
        28: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_unit/runner.rb:50:in `each'
        27: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_unit/runner.rb:50:in `block in load_tests'
        26: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_unit/runner.rb:50:in `require'
        25: from /home/lattis/dev/rails/blorgh/test/blorgh_test.rb:1:in `<top (required)>'
        24: from /home/lattis/dev/rails/blorgh/test/blorgh_test.rb:1:in `require'
        23: from /home/lattis/dev/rails/blorgh/test/test_helper.rb:7:in `<top (required)>'
        22: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
        21: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
        20: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
        19: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
        18: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/railties-5.2.3/lib/rails/test_help.rb:17:in `<top (required)>'
        17: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/migration.rb:598:in `maintain_test_schema!'
        16: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
        15: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:257:in `load_dependency'
        14: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `block in require'
        13: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies.rb:291:in `require'
        12: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/base.rb:27:in `<top (required)>'
        11: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/base.rb:328:in `<module:ActiveRecord>'
        10: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:51:in `run_load_hooks'
         9: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:51:in `each'
         8: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:52:in `block in run_load_hooks'
         7: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:67:in `execute_hook'
         6: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:62:in `with_execution_control'
         5: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:71:in `block in execute_hook'
         4: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/lazy_load_hooks.rb:71:in `instance_eval'
         3: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/railtie.rb:123:in `block (2 levels) in <class:Railtie>'
         2: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/railtie.rb:123:in `each'
         1: from /home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/railtie.rb:124:in `block (3 levels) in <class:Railtie>'
/home/lattis/.local/share/rbenv/versions/2.6.2/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/dynamic_matchers.rb:22:in `method_missing': undefined method `observers=' for ActiveRecord::Base:Class (NoMethodError)

Observers not firing in feature/integration tests using Capybara

I'm using Capybara for integration testing. My observers work fine in my app and in my regular tests, but Capybara feature tests do not trigger any observers no matter what I try. Has anyone dealt with this or is this a known or intentional behavior?

I'm using the latest version of RSpec, Capybara (github masters) and Rails 5.0.0beta3.

Slow app boot when trying to observe ActiveRecord::Base

If you observe ActiveRecord::Base in order to do something if any model is changed there is some bug in how the observers lists are created causing the app boot to take a long time when eager loading code.

In our case we had an observer that removed comments if a model was destroyed and it had associated comments.

I've reproduced the issue here: https://github.com/barsoom/reproduce_observer_error

We don't use observers in any apps anymore, but thought I'd post this in case someone else had the same issue.

ActiveRecord::Base.instantiate_observers does not get called

Hello,

I'm using Rails 5.0.0.1 with latest master rails-observer.

For some reason I couldn't identify, observers listed in config.active_record.observers suddenly stopped being loaded. I traced the issue in reloader.to_prepare's block not being called and thus ActiveRecord::Base.instantiate_observers not being invoked.

Do you have any idea what could be happening?

Test fails with Rails 5.2.2.

Specifically, this line.

On Fedora, we run the test suite:

+ ruby -Ilib:test -e 'Dir.glob '\''./test/*_test.rb'\'', &method(:require)'
Run options: --seed 45546
# Running:
......................F
Failure:
TransactionCallbacksTest#test_after_transaction_callbacks_should_prevent_callbacks_from_being_called [/builddir/build/BUILD/rails-observers-0.1.5/usr/share/gems/gems/rails-observers-0.1.5/test/transaction_callbacks_test.rb:244]:
Expected: [:after_commit]
  Actual: []
bin/rails test builddir/build/BUILD/rails-observers-0.1.5/usr/share/gems/gems/rails-observers-0.1.5/test/transaction_callbacks_test.rb:223
.....................................................
Finished in 5.114705s, 14.8591 runs/s, 31.4779 assertions/s.
76 runs, 161 assertions, 1 failures, 0 errors, 0 skips

Lastly the test suite was executed successfully with 5.2.0.
Currently fails with Rails 5.2.2.

Observers no longer loaded in 0.1.4

I suspect this might well be related to existing issues, but they date back a few years, so I thought I'd open a new issue. After upgrading to 0.1.4 (from 0.1.2) the observers are no longer loaded.

I it looks like there was no 0.1.3 or it was yanked.

The work around is to lock to "0.1.2":

gem "rails-observers", "0.1.2"

This is Rails 4.2

I cannot install the gem from gemfile.

I added gem 'rails-observers' to my gemfile and I ran bundle install. I got

โžœ  test-gem bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching version metadata from https://rubygems.org/..
Fetching dependency metadata from https://rubygems.org/.
Resolving dependencies...
Bundler could not find compatible versions for gem "activemodel":
  In snapshot (Gemfile.lock):
    activemodel (= 5.0.0.1)

  In Gemfile:
    rails (>= 5.0.0.1, ~> 5.0.0) was resolved to 5.0.0.1, which depends on
      activemodel (= 5.0.0.1)

    rails (>= 5.0.0.1, ~> 5.0.0) was resolved to 5.0.0.1, which depends on
      activemodel (= 5.0.0.1)

    rails-observers was resolved to 0.1.2, which depends on
      activemodel (~> 4.0)

    web-console was resolved to 3.4.0, which depends on
      activemodel (>= 5.0)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
Bundler could not find compatible versions for gem "railties":
  In snapshot (Gemfile.lock):
    railties (= 5.0.0.1)

  In Gemfile:
    coffee-rails (~> 4.2) was resolved to 4.2.1, which depends on
      railties (< 5.2.x, >= 4.0.0)

    jquery-rails was resolved to 4.2.1, which depends on
      railties (>= 4.2.0)

    rails (>= 5.0.0.1, ~> 5.0.0) was resolved to 5.0.0.1, which depends on
      railties (= 5.0.0.1)

    rails-observers was resolved to 0.1.0, which depends on
      railties (~> 4.0.0.beta)

    sass-rails (~> 5.0) was resolved to 5.0.6, which depends on
      railties (< 6, >= 4.0.0)

    web-console was resolved to 3.4.0, which depends on
      railties (>= 5.0)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.

For tried this I created a new rails project.

  • Ruby 2.3.0
  • Rails 5.0.0.1

Gemfile and gem list

source 'https://rubygems.org'


# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use jquery as the JavaScript library
gem 'jquery-rails'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

gem 'rails-observers'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platform: :mri
end

group :development do
  # Access an IRB console on exception pages or by using <%= console %> anywhere in the code.
  gem 'web-console'
  gem 'listen', '~> 3.0.5'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
*** LOCAL GEMS ***

actioncable (5.0.0.1)
actionmailer (5.0.0.1)
actionpack (5.0.0.1)
actionview (5.0.0.1)
activejob (5.0.0.1)
activemodel (5.0.0.1)
activerecord (5.0.0.1)
activesupport (5.0.0.1)
arel (7.1.4)
bigdecimal (default: 1.2.8)
builder (3.2.2)
bundler (1.13.6)
bundler-unload (1.0.2)
byebug (9.0.6)
coffee-rails (4.2.1)
coffee-script (2.4.1)
coffee-script-source (1.11.1)
concurrent-ruby (1.0.2)
debug_inspector (0.0.2)
did_you_mean (1.0.0)
erubis (2.7.0)
execjs (2.7.0)
executable-hooks (1.3.2)
ffi (1.9.14)
gem-wrappers (1.2.7)
globalid (0.3.7)
i18n (0.7.0)
io-console (default: 0.4.5)
jbuilder (2.6.1)
jquery-rails (4.2.1)
json (default: 1.8.3)
listen (3.0.8)
loofah (2.0.3)
mail (2.6.4)
method_source (0.8.2)
mime-types (3.1)
mime-types-data (3.2016.0521)
mini_portile2 (2.1.0)
minitest (5.10.1, 5.8.3)
multi_json (1.12.1)
net-telnet (0.1.1)
nio4r (1.2.1)
nokogiri (1.6.8.1)
power_assert (0.2.6)
psych (default: 2.0.17)
puma (3.6.2)
rack (2.0.1)
rack-test (0.6.3)
rails (5.0.0.1)
rails-dom-testing (2.0.1)
rails-html-sanitizer (1.0.3)
rails-observers (0.1.2)
railties (5.0.0.1)
rake (12.0.0, 10.4.2)
rb-fsevent (0.9.8)
rb-inotify (0.9.7)
rdoc (default: 4.2.1)
rubygems-bundler (1.4.4)
rvm (1.11.3.9)
sass (3.4.22)
sass-rails (5.0.6)
spring (2.0.0)
spring-watcher-listen (2.0.1)
sprockets (3.7.0)
sprockets-rails (3.2.0)
sqlite3 (1.3.12)
test-unit (3.1.5)
thor (0.19.4)
thread_safe (0.3.5)
tilt (2.0.5)
turbolinks (5.0.1)
turbolinks-source (5.0.0)
tzinfo (1.2.2)
uglifier (3.0.4)
web-console (3.4.0)
websocket-driver (0.6.4)
websocket-extensions (0.1.2)

Also I tried ran bundle update and then bundle install but it does not work.
I have the same problem with rails 5.0.0.beta3.

NoMethodError for #observe

got error in:
rails-observers-0.1.2/lib/rails/observers/active_model/observing.rb:310 #observe:
private method redefine_method called for Class:SummarySweeper

My code
Model:

 class SummarySweeper < ActionController::Caching::Sweeper
     observe Employee
 end

Controller:

cache_sweeper :summary_sweeper, :only => [ :update, :create, :destroy ]

ActionController:Caching::Sweeper callbacks ignore the cache_sweeper configuration

Documentation is not clear on the usage of cache sweeper. From the examples it appears that the ActiveRecord observers are active only if the sweeper is activated in the controller via cache_sweeper method. However, this is not true - they are just the ordinary AR observers, which in addition also receive callback from the controller. In controller callbacks, @controller variable is set to current controller, while method_missing is rerouted to the @controller. This is why the examples in documentation work - calls to the expire_page and expire_action are routed to the controller only if @controller is set. However, due to rails/rails@91cb99e, if the controller is not set, these methods now raise method_missing exception when sweeper is called outside controller scope.

In documentation it is also not documented how to use controller callbacks explicitly (sweeper should implement controller_callback_method_name or action_callback_method_name).

Bad examples in README

So this was extracted from Rails since most people used observers wrong. Don't you think that examples that uses them in a bad way might invite people to make those mistakes again and again?

Observers should work with persistence, with concerns that shouldn't really be directly in the model. Here's some examples:

class PostObserver < ActiveRecord::Observer
  def after_destroy(post)
    destroy_unused_tags(post.tags)
  end

  private
  def destroy_unused_tags(changed_tags)
    changed_tags.each do |tag|
      tag.destroy if tag.taggings.empty?
    end
  end
end
class PageViewingObserver < ActiveModel::Observer
  def after_create(page_viewing)
    # Assuming the following models work by caching counters and then incrementing them (speed by denormalization, MongoDB, etc.)
    VisitorStatistics.increase_monthly_stats(page_viewing.visitor)
    PageStatistics.increase_monthly_stats(page_viewing.page)
  end
end

Sure, these might still not be optimal, but they are better than an example that sends an email from the persistence layer, every time a model is persisted. Thoughts?

ActionController::Caching::Sweeper controller instance is not thread safe

Hello,

We're using this gem to manage and clean the cache of our site. Thank you for it!

We use puma as the web server for Rails. In production, we configure it to use several threads. Some time ago, we started to get exceptions of an undefined expire_action method:

undefined method `expire_action' for #<ReleaseSweeper:0x000000073b69b8 @_routes=nil, @controller=nil> Did you mean? expire_api_actions

We've some loops in our sweeper and at some point, the @controller variable is lost between the different puma threads.

To solve this issue, we've applied this monkey patch from this comment.

# Fix https://github.com/rails/rails/issues/643
module ActionController::Caching
  class Sweeper < ActiveRecord::Observer
    def controller
      Thread.current["#{self.class.name}_controller"]
    end

    def controller=(controller)
      Thread.current["#{self.class.name}_controller"] = controller
    end

  private

    def method_missing(method, *arguments, &block)
      return if controller.nil?
      controller.__send__(method, *arguments, &block)
    end
  end
end

I see the comment is from 2011, but this code didn't end in the gem. So, I don't know if there's any reason for not adding this code.

Should I create a pull request?

Devise current_user not available when running tests

Upgrade our app from Rails 3.2 to Rails 4.1.5. When I run the app in development mode I can access Devise's current user within a Sweeper's callback. However, when I run tests current_user is nil.

The same code works fine when running tests in 3.2. Could there possibly be some gem load order problem when I'm running tests that might be causing this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.