我正在测试控制器的这一行:
@channel.update_attribute(:active, true)
expect(channel.active).to be_true fails (my variable is named 'channel')
expect(assigns[:channel].active).to be_true passes
assigns[:channel] == channel
=> true
assigns[:channel].active == channel.active
=> false
assigns[:channel].active == channel.reload.active
=> true
我不明白为什么比较运算符会指定[:channel] == channel,但他们的“active”属性不同。
答案 0 :(得分:2)
我认为一个频道是一个ActiveRecord对象,它和做的一样:
channel1 = Channel.find(1)
channel2 = Channel.find(1)
所以channel1 == channel2
因为他们的身份是一样的。 (它们都是频道,并具有相同的ID)
但是如果你更新其中一个,那么另一个将是陈旧的。
channel1.active = "different value"
channel1.save
channel1.active != channel2.active
执行channel2.reload
将从数据库中获取属性,现在
channel1.active == channel2.active
http://api.rubyonrails.org/classes/ActiveRecord/Core.html#method-i-3D-3D
答案 1 :(得分:2)
因为ActiveRecord模型的相等性是基于它们的ID而不是每个属性。所以它是相同的模型,他们只是为他们的"活跃"设置了不同的设置。属性。这就是为什么它重新加载后才有效。
我认为如果你改变第一行,它可能会像你期望的那样:
@channel.update(active: true)
答案 2 :(得分:0)
我不确定在您的具体情况下发生了什么确切,但总体情况并不奇怪:
class Foo
attr_reader :bar
def initialize
@bar = Bar.new
end
def ==(*) true end
class Bar
def ==(*) false end
end
end
a = Foo.new
b = Foo.new
a == b
# => true
a.bar == b.bar
# => false
这只是面向对象封装的结果。最多a
决定它是否认为它等于b
,并且最多a.bar
来决定它是否认为它等于{{1}并且没有什么可以强制要求两者达成一致。
在您的情况下,似乎存在一些缓存一致性问题。您似乎有两个不同的对象,它们都代表相同的数据库记录,其中一个对象具有陈旧数据。