有没有办法通过回调挂钩save!
?
我正在寻找类似的东西:
class CompositeService < Service
attr_accessible :subservices
before_save :save_subservices
before_save :save_subservices! if bang_save?
private
def save_subservices
@subservices.each(&:save)
end
def save_subservices!
@subservices.each(&:save!)
end
end
save!
级联,并在(虚假)关联save!
上调用subservices
。
答案 0 :(得分:2)
从技术上讲,你可以做到这一点,但我建议不要在生产中使用这种方法,因为它可以在更新的轨道中改变。这是错的。
您可以检查回调之前的调用堆栈并检查是否有保存!方法
class CompositeService < Service
before_save :some_callback
def some_callback
lines = caller.select { |line| line =~ /persistence.rb/ && line =~ /save!/ }
if lines.any?
@subservices.each(&:save!)
else
@subservices.each(&:save)
end
end
end
答案 1 :(得分:1)
我想知道:这个额外的逻辑是否必要?
如果save
上的每个@subservices
方法都遵循ActiveRecord save
语义,那么您可能会免费获得正确的行为。
换句话说,请确保您的save
方法返回true
或false
表示成功或失败。然后,复合代码变得如此简单:
class CompositeService < Service
attr_accessible :subservices
before_save :save_subservices
private
def save_subservices
@subservices.all?(&:save)
end
end
如果您的任何子服务无法保存,则save_subservices
回调将返回false
,这将中止回调链。这将导致包裹save
返回false
。在save!
的情况下,它会引发异常。
composite.save
# => false
composite.save!
# => ActiveRecord::RecordNotSaved
答案 2 :(得分:0)
查看ActiveRecord自动保存属性:
http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html