别名方法是否令人不悦?
我正在开发一个在线商店,客户需要能够删除订单并自动重新进货(例如,测试订单)。 这是我第一次尝试实现这一点:
class Order < ActiveRecord::Base
def destroy_and_restock
restock_products
destroy
end
protected
def restock_products
line_items.each do |li|
li.product.quantity_on_hand += li.quantity
li.product.save
end
end
end
但是如果我稍后需要创建另一个 destroy_and_x
方法怎么办? 为什么不允许 X 作为参数传递给 destroy() 方法? 所以现在我正在考虑这样做:
alias :old_destroy :destroy
def destroy(options = {})
if options['restock'] == true
restock_products
end
old_destroy
end
protected
def restock_products
line_items.each do |li|
li.product.quantity_on_hand += li.quantity
li.product.save
end
这更具可扩展性,但让我感觉有点肮脏。 难道我觉得肮脏有错吗? 有更好的方法吗?
I'm developing an online store, and the customer needs the ability to delete an order and have its products automatically restocked (e.g., for test orders). Here's my first try at implementing this:
class Order < ActiveRecord::Base
def destroy_and_restock
restock_products
destroy
end
protected
def restock_products
line_items.each do |li|
li.product.quantity_on_hand += li.quantity
li.product.save
end
end
end
But what if I need to create another destroy_and_x
method later? Why not allow that X to be passed as a parameter to the destroy()
method? So now I'm thinking of going with this:
alias :old_destroy :destroy
def destroy(options = {})
if options['restock'] == true
restock_products
end
old_destroy
end
protected
def restock_products
line_items.each do |li|
li.product.quantity_on_hand += li.quantity
li.product.save
end
This is more extensible, but makes me feel somewhat dirty. Am I wrong to feel dirty? Is there a better way of doing this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我会说“是的,这很脏。” 您的目的不是修改“destroy”方法的行为,而是执行一些特定于域的工作,然后运行
destroy
。 您的第一种方法很棒——定义一个执行您想要的操作的方法,并根据需要调用destroy
。 我认为,正如您所考虑的,“包装”或“猴子修补”方法是一种在无法使用标准 OO 方法时最好应用的技术,例如,当您需要修改/增强某个方法中的行为时。在您的控制范围之外定义和使用的类。即使您正在考虑修改
destroy
方法本身的行为,我也建议在这里重写该方法,而不是包装它:I'd say "yes, this is dirty." Your intention isn't to modify the behavior of the 'destroy' method, but rather to do some domain-specific work, then run
destroy
. Your first approach is great -- define a method that does what you want, and invokedestroy
as needed. I think that 'wrapping' or 'monkey-patching' a method, as you're considering, is a technique that's best applied when standard OO approaches can't be used -- eg, when you need to modify/augment behavior in a class that is defined and used outside of your realm of control.Even if you are considering modifying the behavior of the
destroy
method itself, I'd suggest overriding the method here, rather than wrapping it:只用一个块怎么样? 然后你就不必在课堂上设计这个函数时费尽心思,你可以在需要时做更多的事情:
然后像这样调用它:
我想不出这个函数的好名字......但我希望你明白了。
How about just use a block? Then you dont have to pull your hair apart while designing this in the class and you can do more as and when you need to:
Then call it like this:
I can not think of a good name for this function... but I hope you get the idea.
霍拉斯,我误解了你的问题。 我想你正在寻找这个:
http://api.rubyonrails.org/classes/ ActiveRecord/Callbacks.html
现在,您可以保护您的方法并根据需要添加任意数量的 before_destroy 内容。 希望这对您有用,而不会覆盖破坏。
祝你好运。
Horace, I misunderstood your question. I think you are looking for this:
http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
Now you can keep your method protected and add as many before_destroy things as you like. Hope this works for you without overriding destroy.
Best of luck.
如果猴子补丁不能让你晚上睡觉,你可以通过子类化来达到同样的目的。 当我需要快速破解或快速调试破解时,我也会进行猴子补丁。
If monkey patching doesn't let you sleep at night, you can achieve the same thing by subclassing. When I'm in the need of a quick hack, or a quick debug hack, I monkey patch as well.