在 Rails 6 中使用不同的表创建一个 ActiveRecord::Relation

问题描述

我正在尝试升级分区 gem 以便在 Rails 6.1 中使用分区(我正在升级现有的 Rails 应用程序)。
我已经设法让一切正常工作,除了一部分:
在分区gem中,为了查询分区表,
他们将创建一个与“正确”的 arel_table(即我们要查询的实际分区表)的新关系。

以下语法适用于 Rails 3.2:

    def self.from_partition(*partition_key_values)
      table_alias_name = partition_table_alias_name(*partition_key_values)
      return ActiveRecord::Relation.new(self,self.arel_table_from_key_values(partition_key_values,table_alias_name))
    end

其中 self.arel_table_from_key_values(partition_key_values,table_alias_name) 是指向正确表名(分区)的 Arel::Table 实例。

我已将语法更新为:

    def self.from_partition(*partition_key_values)
      table_alias_name = partition_table_alias_name(*partition_key_values)
      return ActiveRecord::Relation.new(self,table: self.arel_table_from_key_values(partition_key_values,table_alias_name))
    end

现在的问题是,当我尝试运行在 Rails 3.2 中工作的命令时,例如:

ItemLine.from_partition(11,1).find_by_code("1111")

我收到诸如 undefined method `find_by_code' for #<ActiveRecord::Relation 之类的错误 或者如果我尝试运行

ItemLine.from_partition(11,1).last

我得到: undefined local variable or method `implicit_order_column' for #<ActiveRecord::Relation

似乎我以错误的方式创建了关系。
在 Rails 6.1 中使用不同的 arel 表创建 ActiveRecord::Relation 的最佳/正确方法是什么?

谢谢!

解决方法

ActiveRecord的源代码中挖掘之后,
我能够通过以下方式解决它:

    def self.from_partition(*partition_key_values)
      table_alias_name = partition_table_alias_name(*partition_key_values)
      table = self.arel_table_from_key_values(partition_key_values,table_alias_name)
      tm = ActiveRecord::TableMetadata.new(self,table)
      predicate_builder = ActiveRecord::PredicateBuilder.new(tm)
      return ActiveRecord::Relation.create(self,table: table,predicate_builder: predicate_builder)
    end

我仍然需要对此解决方案进行一些测试,但到目前为止一切顺利! :-)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...