别名方法是否令人不悦?

发布于 2024-07-24 20:26:15 字数 799 浏览 4 评论 0原文

我正在开发一个在线商店,客户需要能够删除订单并自动重新进货(例如,测试订单)。 这是我第一次尝试实现这一点:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏日浅笑〃 2024-07-31 20:26:15

我会说“是的,这很脏。” 您的目的不是修改“destroy”方法的行为,而是执行一些特定于域的工作,然后运行 ​​destroy。 您的第一种方法很棒——定义一个执行您想要的操作的方法,并根据需要调用destroy。 我认为,正如您所考虑的,“包装”或“猴子修补”方法是一种在无法使用标准 OO 方法时最好应用的技术,例如,当您需要修改/增强某个方法中的行为时。在您的控制范围之外定义和使用的类。

即使您正在考虑修改destroy方法本身的行为,我也建议在这里重写该方法,而不是包装它:

def destroy(options = {})
  restock_products if options['restock']
  super() # I think parens are necessary here, to avoid passing options up the chain
end

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 invoke destroy 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:

def destroy(options = {})
  restock_products if options['restock']
  super() # I think parens are necessary here, to avoid passing options up the chain
end
此生挚爱伱 2024-07-31 20:26:15

只用一个块怎么样? 然后你就不必在课堂上设计这个函数时费尽心思,你可以在需要时做更多的事情:

def destroy_after &block
  yield if block
  destroy
end

然后像这样调用它:

order.destroy_after { order.restock_products }

我想不出这个函数的好名字......但我希望你明白了。

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:

def destroy_after &block
  yield if block
  destroy
end

Then call it like this:

order.destroy_after { order.restock_products }

I can not think of a good name for this function... but I hope you get the idea.

要走就滚别墨迹 2024-07-31 20:26:15

霍拉斯,我误解了你的问题。 我想你正在寻找这个:

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.

软甜啾 2024-07-31 20:26:15

如果猴子补丁不能让你晚上睡觉,你可以通过子类化来达到同样的目的。 当我需要快速破解或快速调试破解时,我也会进行猴子补丁。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文