红宝石常数在其他课程或测试中没有被提升

时间:2022-04-08 17:18:04

I have a Product model with a constant defined on it:

我有一个带有常量的Product模型:

class Product < ActiveRecord::Base

  EMPTY = find_by_name("None Added")

end

And then I have a Company model that attempts to make use of the constant:

然后我有一个试图利用常量的公司模型:

class Company < ActiveRecord::Base

  belongs_to :product

  before_save :default_values

  def default_values
    self.product ||= Product::EMPTY
  end

end

I am using RSpec and FactoryGirl for my tests.

我正在使用RSpec和FactoryGirl进行测试。

describe 'default initialization values' do
    before(:each) do
      create(:product, name: "None Added")
    end

    it 'defaults to the correct product if it is nil' do
      company = create(:company, product: nil)

      expect(company.product).to_not eq(nil)
      expect(company.product.name).to eq("None Added")
    end 
end

My test keeps failing because the product remains nil. And when I check the trace it seems my constant Product::EMPTY is returning a nil value. When I drop the constant on a view or in the rails console it gives me the correct value. What could I be missing?

我的测试一直失败,因为产品仍然是零。当我检查跟踪时,似乎我的常量Product :: EMPTY返回一个nil值。当我将常量放在视图或rails控制台中时,它会给我正确的值。我能错过什么?

2 个解决方案

#1


2  

The expression EMPTY = find_by_name("None Added") is loaded and evaluated when the class is loaded. When you run your specs that means that find_by_name("None Added") will find nothing and EMPTY will always be nil. That will not change if you create a product named None Added later on.

加载类时,将加载并计算表达式EMPTY = find_by_name(“None Added”)。当您运行您的规范时,这意味着find_by_name(“None Added”)将找不到任何内容,EMPTY将始终为nil。如果您创建名为“无添加”的产品,则不会更改。

Change your code to something like this to ensure that always an empty product exists:

将您的代码更改为类似的内容,以确保始终存在空产品:

EMPTY = find_or_create_by_name("None Added")

Or use a class method instead that is evaluated everytime:

或者使用每次评估的类方法:

def self.empty
  find_by_name("None Added")
end

def default_values
  self.product ||= Product.empty
end

#2


1  

You doesn't have Product named "None Added" in your test database by the time the constant is set, so find_by_name("None Added") returns nil. Notice that EMPTY constant is set when the Product class is evaluated and it's earlier than you create your 'None Added' product.

在设置常量时,您的测试数据库中没有名为“None Added”的产品,因此find_by_name(“None Added”)返回nil。请注意,在评估Product类时设置EMPTY常量,并且它早于创建“None Added”产品。

#1


2  

The expression EMPTY = find_by_name("None Added") is loaded and evaluated when the class is loaded. When you run your specs that means that find_by_name("None Added") will find nothing and EMPTY will always be nil. That will not change if you create a product named None Added later on.

加载类时,将加载并计算表达式EMPTY = find_by_name(“None Added”)。当您运行您的规范时,这意味着find_by_name(“None Added”)将找不到任何内容,EMPTY将始终为nil。如果您创建名为“无添加”的产品,则不会更改。

Change your code to something like this to ensure that always an empty product exists:

将您的代码更改为类似的内容,以确保始终存在空产品:

EMPTY = find_or_create_by_name("None Added")

Or use a class method instead that is evaluated everytime:

或者使用每次评估的类方法:

def self.empty
  find_by_name("None Added")
end

def default_values
  self.product ||= Product.empty
end

#2


1  

You doesn't have Product named "None Added" in your test database by the time the constant is set, so find_by_name("None Added") returns nil. Notice that EMPTY constant is set when the Product class is evaluated and it's earlier than you create your 'None Added' product.

在设置常量时,您的测试数据库中没有名为“None Added”的产品,因此find_by_name(“None Added”)返回nil。请注意,在评估Product类时设置EMPTY常量,并且它早于创建“None Added”产品。