Rails Active Record 中如何使用 delegate 到一个不相关的 class 里的方法

color_huo · 2015年06月15日 · 最后由 color_huo 回复于 2015年06月16日 · 3371 次阅读

例如:

  • 我有一个 order model
class Order < ActiveRecord::Base
  def pay
    base_handler.init_with(self)
  end
end
  • 对于不同类型的 order,我想有不同的处理,于是我定义了以下几个 class
class BaseHandler
  def initialize
    #
  end

  def init_with order
    # 根据 order 的类型来决定使用 way_one 还是 way_two
  end

  def pay
  end
end

class WayOne < BaseHandler
  def pay
    # 流程 1
  end
end

class WayTwo < BaseHandler
  def pay
    # 流程 2
  end
end
  • 于是,我想将 pay 方法 delegate 到 class base_handler 里面去,该如何做呢?
  • 还是说,这样根本就不适合使用 delegate 的方式去做?
  • 对 rails 里面使用 delegate 不熟悉,希望大家多多指教!

参考文章: Rails' delegates are even more useful than I knew delegation-in-ruby

class BaseHandler

  module ModelMethods
    def pay
    end
  end

end

class Order < ActiveRecord::Base
  include BaseHandler::ModelMethods
end

写个模块然后引入到 Order 里

看看元编程动态方法调用,不用整那么麻烦

比如酱紫

@order.send(#{your_dynamic_method_by_type}, args)
class Order < ActiveRecord::Base
  def pay
    case order_type
    when 'pay_one'
      pay_one
    when 'pay_two'
      pay_two
    end
  end

  def pay_one
  end

  def pay_two
  end
end

也可以直接用 AR 的 Single table inheritance

class Order < ActiveRecord::Base
end

class OrderFoo < Order
  def pay
  end
end

class OrderBar < Order
  def pay
  end
end

create_table :orders do |t|
  t.string :type
end
5 楼 已删除

#1 楼 @lolychee 直接引入模块,可能对于有些公共方法在 BaseHandler, 特殊方法放在各个子类那里的支持不太好

#2 楼 @PlayMonkey send 的话可能要针对不同类型有不同的方法名,不过其实有可能做的东西是一样的

#3 楼 @rei 抛砖引玉,看有没有特殊的思路而已,别见怪

#7 楼 @color_huo 这些都是你自己定规则的,send 哪个方法可以动态配置,其实和 #3 楼 rei 的意思差不多,方式不一样而已 XD

#4 楼 @quakewang 👍 Single table inheritance 这个方式实现挺好的:数据集中管理,实现逻辑分离,比较好维护。适用于:多种类型订单的生成,多种渠道的消息推送,多种支付的对接。。。

#9 楼 @PlayMonkey 恩,是的,本意是想了解一下 delegate 的用法而已

需要 登录 后方可回复, 如果你还没有账号请 注册新账号