rails-observers icon indicating copy to clipboard operation
rails-observers copied to clipboard

@controller in Sweeper is set to nil when running rspec controller test

Open nnattawat opened this issue 10 years ago • 4 comments

I am in the process of upgrading rails 3.2 to 4.1.8. So, I add the gem to make the app running without changing any code. The observer and sweeper actually works fine when I did manual test. However, when I run rspec test, I got missing method error and @controller was nil.

I need to add @controller ||= ActionController::Base.new in my sweeper for the hot fix.

nnattawat avatar Dec 12 '14 02:12 nnattawat

I’ve just run into this issue too – with Rails 5.0.1, git version of this gem and standard minitest. Proposed hot fix works for me.

To add some more details, the error I hit was:

ProposalsControllerTest#test_listing_proposals:
NoMethodError: undefined method `expire_page' for #<ProposalSweeper:0x00560a65f14468 @controller=nil>
    app/models/proposal_sweeper.rb:6:in `after_save'
    test/controllers/proposals_controller_test.rb:62:in `block (2 levels) in <class:ProposalsControllerTest>'
    test/controllers/proposals_controller_test.rb:62:in `times'
    test/controllers/proposals_controller_test.rb:62:in `block in <class:ProposalsControllerTest>'

Although this is an example of a failing controller test, I get failures for model tests as well.

My sweeper’s code:

class ProposalSweeper < ActionController::Caching::Sweeper
  observe Proposal

  def after_save(record)
    expire_page :controller => 'proposals', :action => %w[ index new ]
  end 
end

xHire avatar Jan 02 '17 11:01 xHire

I just run into this issue too. I use Rails 4.2.8. @controller is nil.

NoMethodError:
       undefined method `expire_action' for #<TurnSweeper:0x007f92bc252af0 @controller=nil>
       Did you mean?  expire_cost_fragment
     # /Users/yazhou/.rvm/gems/ruby-2.4.0@gmc/gems/rails-observers-0.1.4/lib/rails/observers/action_controller/caching/sweeper.rb:57:in `method_missing'

gracemdsol avatar Jul 07 '17 18:07 gracemdsol

I have the same issue but in my running application (not RSpec) with rails 5.1.4.

In my controller:

class FormulasController < ApplicationController
  ...
  caches_action :index
  cache_sweeper :formulas_sweeper, only: :index

  def index
    ...
  end
end

And my Sweeper class:

class FormulasSweeper < ActionController::Caching::Sweeper
  observe Import

  def after_update(import)
    expire_action controller: 'formulas', action: 'index'
  end
end

The Sweeper is running and failing with:

NoMethodError: undefined method `expire_action' for #<FormulasSweeper:0x00000004e935f0 @controller=nil>
	from app/sweepers/formulas_sweeper.rb:6:in `after_update'
	from (irb):2

@nnattawat's fix

Updating my Sweeper as following:

class FormulasSweeper < ActionController::Caching::Sweeper
  observe Import

  def after_update(import)
    @controller ||= ActionController::Base.new
    expire_action controller: 'formulas', action: 'index'
  end
end

Makes the code fail with:

NoMethodError: undefined method `host' for nil:NilClass
	from app/sweepers/formulas_sweeper.rb:7:in `after_update'
	from (irb):2

This is due to the fact that ActionController::UrlFor.url_options is expecting a request object which is nil in my case.

zedtux avatar Nov 14 '17 09:11 zedtux

I was getting undefined for expire_page and the only thing that fixed it for me was changing it to ApplicationController.expire_page as mentioned here: https://github.com/rails/rails-observers/issues/4#issuecomment-51510874

WesleyKapow avatar Jul 20 '19 13:07 WesleyKapow