我有一个控制器,可以计算用户访问页面的次数。 我正在尝试将该计数提取到设置会话变量的 getter 和 setter 中。 获得有效,但设置没有。 这是控制器:
class StoreController < ApplicationController
def index
@products = Product.order(:title)
v = store_visits + 1
store_visits = v # tests fail if I do it like this
# store_visits += 1 # Undefined method '+' for NilClass if i do it like this
@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
这是一个失败的测试:
require 'test_helper'
class StoreControllerTest < ActionController::TestCase
test "should count store visits" do
get :index
assert session[:store_counter] == 1
get :index
assert session[:store_counter] == 2
end
end
为什么它不是设置,为什么如果我使用+=
store_visits返回 nil? 任何帮助,不胜感激。
注意:最初我将方法提取到一个关注点,但我对其进行了编辑以消除关注点,因为问题不在于关注点,而在于设置器和/或获取器。
更新:添加日志记录语句后,很明显永远不会到达 store_visits=() 方法的内部(但不知何故没有抛出错误)。 但是,如果我将其重命名为 assign_store_visits(),它确实会被调用,并且确实会更新会话变量。 所以我猜这要么是一个错误,其中 setter 方法在控制器中不起作用(这是 Rails 4.0.0),要么它们被故意阻止(在这种情况下,例外会很好)。
尝试切换到include ActiveSupport::Concern
这将提供实例方法而不是类方法
您需要将关注点内的方法包装在包含的块中,例如:
module Visits
extend ActiveSupport::Concern
included do
#private
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
# private
end
end
end
这样做将使这些方法可用作控制器内的实例方法。