如何使用新方法扩展ActiveRecord关系?

时间:2016-01-11 19:18:37

标签: ruby-on-rails activerecord

让我们想象一下,我有这样简单的ActiveRecord模型:

class Post < ActiveRecord::Base
  belongs_to :category
end

class Category < ActiveRecord::Base
  has_many :posts
  has_many :published_posts, -> { where(:published => true) }
end

我想创建一个模块Reindexable,它将一个名为reindex的方法添加到基类中。我希望能够通过以下3种方式调用此方法:

Place.reindex
Place.reindex(Place.where(:published => true))
Place.where(:published => true).reindex
Category.first.places.reindex

在这个方法的内部,我应该可以这样做:

Reindexer.new(relation).reindex # how can I get relation here?

在Ruby-on-Rails中执行此操作的正确方法是什么?如何在所有这些情况下访问当前关系?

1 个答案:

答案 0 :(得分:-1)

我试图将代码包含在动态添加到任何AR类的ActiveRecord_Relation类中。

如果您需要将.to_csv添加到MyModel.all.to_csv等所有调用中:

型号:

class MyModel < ActiveRecord::Base
  include ToCsv
end

您要包含的模块

module ToCsv
  extend ActiveSupport::Concern

  #  Dynamically including our Relation and extending current class
  #
  def self.included(child_class)
    child_class.const_get('ActiveRecord_Relation').include(RelationMethods)
    child_class.extend(ExtendMethods)
  end

  #  Instance Method
  #
  def to_csv(opts = {})
  end

  #  Module containing methods to be extended into the target
  #
  module ExtendMethods

    #  Allowing all child classes to extend ActiveRecord_Relation
    #
    def inherited(child_class)
      super + (child_class.const_get('ActiveRecord_Relation').include(RelationMethods) ? 1 : 0 )
    end
  end

  #  Holds methods to be added to relation class
  #
  module RelationMethods
    extend ActiveSupport::Concern

    #  Relation Method
    #
    def to_csv(opts = {})
    end
  end
end