small medium large xlarge

Generic-user-small
27 Feb 2016, 13:22
Dustin King (7 posts)

After doing the exercises where we add the counting of page visits (which worked fine getting and setting session[:store_counter], I tried to extract that functionality to a concern (but it doesn’t seem to matter whether the methods are in the concern or the StoreController itself, same result).

Here’s the controller code:

class StoreController < ApplicationController
	def index
		@products = Product.order(:title)
		v = store_visits + 1
		store_visits = v
		@visits = store_visits
	end
	
	def store_visits
		if session[:store_counter].nil?
			session[:store_counter] = 0
		end
		session[:store_counter]
	end	

	def store_visits=(value)
		session[:store_counter] = value
	end
end

And a failing test:

require 'test_helper'

class StoreControllerTest < ActionController::TestCase
  test "should get index" do
    get :index
    assert_response :success
    assert_select '#columns #side a', minimum: 4
    assert_select '#main .entry', 3
    assert_select 'h3', 'Programming Ruby 1.9'
    assert_select '.price', /^\$\d{1,3}(,\d\d\d)*\.\d\d$/
  end
  
  test "should count store visits" do
  	get :index
  	assert session[:store_counter] == 1
  	get :index
  	assert session[:store_counter] == 2
  end
  
  test "should not show low store visits" do
  	1.upto 5 do |n|
  		get :index
  		assert_select '#visits', false
  	end
  	
  	get :index
  	assert_select '#visits', /6 times/
  end

end

What’s really weird is if I do store_visits += 1 instead of doing the get and set separately, I get these errors:

  1) Error:
StoreControllerTest#test_should_count_store_visits:
NoMethodError: undefined method `+' for nil:NilClass
    app/controllers/store_controller.rb:5:in `index'
    test/controllers/store_controller_test.rb:14:in `block in <class:StoreControllerTest>'

  2) Error:
StoreControllerTest#test_should_get_index:
NoMethodError: undefined method `+' for nil:NilClass
    app/controllers/store_controller.rb:5:in `index'
    test/controllers/store_controller_test.rb:5:in `block in <class:StoreControllerTest>'

  3) Error:
StoreControllerTest#test_should_not_show_low_store_visits:
NoMethodError: undefined method `+' for nil:NilClass
    app/controllers/store_controller.rb:5:in `index'
    test/controllers/store_controller_test.rb:22:in `block (2 levels) in <class:StoreControllerTest>'
    test/controllers/store_controller_test.rb:21:in `upto'
    test/controllers/store_controller_test.rb:21:in `block in <class:StoreControllerTest>'

Any help is appreciated.

Edit: This is cross-posted from StackOverflow.

Generic-user-small
28 Feb 2016, 18:30
Dustin King (7 posts)

Update: After adding logger.debug statments, it’s obvious that the inside of the store_visits=() method is never reached (but somehow an error is not thrown). However, if I rename it to assign_store_visits(), it does get called, and does update the session variable. So I’m guessing this is either a bug where setter methods don’t work in controllers (this is Rails 4.0.0) or they’re intentionally blocked (in which case, an exception would be nice).

You must be logged in to comment