gpt4 book ai didi

ruby-on-rails - Rails 中 after_create 回调的优雅替代方案?

转载 作者:行者123 更新时间:2023-12-04 00:40:09 42 4
gpt4 key购买 nike

我有两个模型

class Contract < ActiveRecord::Base
has_many :transactions
end

class Transaction < ActiveRecord::Base
belongs_to :contract
after_create :mark_contract_as_live
def mark_contract_as_live
k = self.contract
if !k.is_live
k.update_attributes(:is_live => true)
end
end
end

is_live 是契约(Contract)模型中的 bool 字段。合约在创建时默认为不存在(is_live => false)。当第一笔交易被记录时,它被标记为实时(is_live => true)。使用上面的解决方案,这意味着每次创建事务都需要调用数据库来检查合约是否处于事件状态。有没有替代方案?

如果合约有数千笔交易,这意味着这将被调用数千次,尽管它只与第一笔交易相关。

在一般意义上,什么是实现回调的优雅方式。这看起来很乱?

最佳答案

class Contract < ActiveRecord::Base
has_many :transactions

def mark_as_live
update(is_live: true) unless is_live?
end
end

class Transaction < ActiveRecord::Base
belongs_to :contract

after_create :mark_contract_as_live

private

def mark_contract_as_live
contract.mark_as_live
end
end

它是 Contract关心契约(Contract)是否应该被标记为有效的类责任。 Transaction类不应该处理这个。所以我创建了一个 mark_as_liveContract类并在 Transaction 中调用它 after_create打回来。

我更喜欢在 mark_as_live 中使用保护子句像这样的方法:
def mark_as_live
return if is_live?

update(is_live: true)
end

但因为它是一个非常短的方法,它可能不值得。

另请注意 ActiveRecord添加方法如 xxx?用于 bool 字段。方法末尾的问号更清楚地传达了您想说的内容。

最后,但这是一个品味问题,我不喜欢在 bool 属性前加上 is_xxx .我不使用 RSpec并且可能是错误的,但我认为它添加了一些谓词匹配器,例如 be_xxx对于 xxx属性,使用 is_xxx 可能会很奇怪属性。因为很多人都在使用 RSpec ,它可能会成为一种约定。

If contract has thousands of transactions, that means this will be called thousands of times although it is only relevant to the very first transaction.


Contract如果您像这样创建事务,实例仍将被加载: contract.transactions.create(transaction_params) .所以调用 is_live?将免费提供,您不必担心。

关于ruby-on-rails - Rails 中 after_create 回调的优雅替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19719308/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com