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”产品。