Rails:如何区分保持属性不变与显式将新值设置为与旧值相同?
Rails: how to tell the difference between leaving an attribute unchanged vs explicitly setting the new value to be the same as the old value?
ActiveRecord User
有 email
和 email_verified
。如果电子邮件发生变化,它将 email_verified
设置为 false 使用:
before_save :process_new_email, if: :email_changed?
process_new_email
基本上就是:
def process_new_email
self.email_verified = false
end
但是,对于 user.update(email: email, email_verified: true)
,如果 email_verified
之前是 true
,这也会将 email_verified
设置为 false。
即这失败了:
user = create(:user, email: 'test@example.com', email_verified: true)
user.update!(email: 'other@example.com', email_verified: true)
expect(user.email_verified).to eq(true)
这就过去了:
user = create(:user, email: 'test@example.com', email_verified: true)
user.update!(email: 'other@example.com')
expect(user.email_verified).to eq(false)
如何让两个测试用例都通过?
我认为您可以使用 ActiveRecord 为您创建的 email_verified_came_from_user?
方法(它为每个属性创建该方法)。
例如检查这个:
user = User.find_by(email: 'test@example.com')
user.email_came_from_user? # => false
user.email = 'test@example.com' # setting the same so no change
user.email_came_from_user? # => true
所以,我会做类似的事情:
def process_new_email
self.email_verified = false unless email_verified_came_from_user?
end
如果已更改,请尝试还原 email_verified。
before_save :revert_email_verified, if: :email_verified_changed?
before_save :process_new_email, if: :email_changed?
def revert_email_verified
self.email_verified = email_verified_was
end
ActiveRecord User
有 email
和 email_verified
。如果电子邮件发生变化,它将 email_verified
设置为 false 使用:
before_save :process_new_email, if: :email_changed?
process_new_email
基本上就是:
def process_new_email
self.email_verified = false
end
但是,对于 user.update(email: email, email_verified: true)
,如果 email_verified
之前是 true
,这也会将 email_verified
设置为 false。
即这失败了:
user = create(:user, email: 'test@example.com', email_verified: true)
user.update!(email: 'other@example.com', email_verified: true)
expect(user.email_verified).to eq(true)
这就过去了:
user = create(:user, email: 'test@example.com', email_verified: true)
user.update!(email: 'other@example.com')
expect(user.email_verified).to eq(false)
如何让两个测试用例都通过?
我认为您可以使用 ActiveRecord 为您创建的 email_verified_came_from_user?
方法(它为每个属性创建该方法)。
例如检查这个:
user = User.find_by(email: 'test@example.com')
user.email_came_from_user? # => false
user.email = 'test@example.com' # setting the same so no change
user.email_came_from_user? # => true
所以,我会做类似的事情:
def process_new_email
self.email_verified = false unless email_verified_came_from_user?
end
如果已更改,请尝试还原 email_verified。
before_save :revert_email_verified, if: :email_verified_changed?
before_save :process_new_email, if: :email_changed?
def revert_email_verified
self.email_verified = email_verified_was
end