代码之家  ›  专栏  ›  技术社区  ›  KaptajnKold

子类化模型在开发环境中会导致NameError,但在测试中不会

  •  0
  • KaptajnKold  · 技术社区  · 17 年前

    这是我的行动模式:

    class Action < ActiveRecord::Base
    end
    
    class Fold < Action
    end
    
    class Check < Action
    end
    
    class Call < Action
    end
    
    class Bet < Action
    end
    

    在另一个模型中,我有这个

    class Deal < ActiveRecord::Base
      def Deal.parse_action(action_string)
        case action_string
        when "folds":   Fold.new()
        when "checks":  Check.new()
        when "calls":   Call.new()
        when "bets":    Bet.new()
        when "raises":  Bet.new()
        else nil   
        end
      end
      # ...
    end
    

    现在,当我在单元测试中测试它时,如果它起作用,那么一切看起来都是有效的。但在开发模式下启动web服务器后,我会得到以下信息:

    NameError (uninitialized constant Deal::Fold):
      app/models/deal.rb:115:in `parse_action'
      ...
    

    为什么它认为Fold存在于名称空间交易中?为什么在测试环境中不会发生这种情况?

    3 回复  |  直到 17 年前
        1
  •  1
  •   Jordan Brough    17 年前

    不是这么说的 Fold 存在于 Deal 命名空间,它表示它正在寻找常量 折叠 处理 . 例如,尝试以下方法:

    class Foo 
      def test; puts Bar; end
    end
    Foo.new.test
    

    你会得到这个:

    NameError: uninitialized constant Foo::Bar
      from (irb):3:in `test'
      from (irb):7
      from :0
    

    Rails为您自动加载常量,我猜问题在于您没有 折叠 在其自己的文件中初始化。试着把 折叠 将类定义放入它自己的文件中-- app/models/fold.rb Action case 声明,比如 x = Action 就在案件审理之前。如果这有效,那么你需要 require "action.rb" deal.rb 因为问题是您的测试代码正在加载action.rb(可能是通过其他测试),而您的生产代码没有加载action.rb。

        2
  •  0
  •   Andrew Grimm Alex Wayne    17 年前

    我在工作中不使用Rails,但有时会遇到这样一种情况,即在运行测试时知道一个类,但在运行可执行文件时却不知道。这是因为我在测试文件中为相关文件提供了必要的“require”语句,但我还没有在生产代码中提供必要的“require”语句。

        3
  •  -1
  •   vrish88    17 年前

    在Ruby中,向已声明的类添加方法如下:

      class Deal < ActiveRecord::Base
        def self.parse_action(action_string)
          case action_string
            when "folds":   Fold.new
            ....
    

    另外(很抱歉吹毛求疵),但是你不需要括号 Fold.new