ActiveRecord的依赖树("删除记录时将删除的内容")

时间:2015-02-26 14:54:46

标签: ruby activerecord

我正在尝试构建一种为ActiveRecord构建依赖关系树的灵活方法。 第一个版本已经很好地工作但在所有模型类中需要其他方法来收集子查询。 现在是时候自动完成了。我已经有一个适用于普通 has_many 查询的工作版本。 在我开始添加其他案例之前,我想知道我是否正朝着正确的方向前进。也许我只是错过了现有的解决方案。

这是我的代码:

# dropped into config/initializers/active_record.rb for quick testing

class ActiveRecord::Base

  class << self

    def dependency_tree(query = nil)
      query ||= self
      tree = {}

      own_ids_sql =  Arel.sql(self.select('id').to_sql)

      reflect_on_all_associations.collect do |relationship|
        if relationship.options[:dependent] == :destroy
          if relationship.inverse_of
            # normal has many

            base        = relationship.inverse_of.active_record
            foreign_key = base.connection.quote_column_name(relationship.inverse_of.association_foreign_key)
            table_name  = base.quoted_table_name
            condition   = "#{table_name}.#{foreign_key} IN (#{own_ids_sql})"

            tree[relationship.name] = {
              count: base.where(condition).count,
              sub: base.where(condition).dependency_tree
            }

          else
            # TODO : figure out the rest
            #        without auto inverse, like polymorphic
            #        maybe STI too? manual conditions on relation?

          end
        end
      end

      tree
    end

  end

  def dependency_tree
    self.class.dependency_tree(self.class.where(id: id))
  end

end

它构建递归子查询,始终包括下一级别的先前条件。目前它只计算依赖=破坏。

使用子查询而不是任何实际对象,即使对于数千个项目,也可以在数据库中获得快速查询,如果不需要,则无需加载任何实际数据。 在我的测试项目中,我可以轻松地使用上面的代码构建一个树,其中100k +项嵌套4层深。

思想,想法,建议?

0 个答案:

没有答案