【问题标题】:How to get the arel table of a habtm association?如何获取habtm关联的arel表?
【发布时间】:2012-01-05 17:55:22
【问题描述】:

我有两个具有 HABTM 关联的 ActiveRecord 模型。

我想写一个scope 来使用 Arel 获取孤儿记录。

我的问题是我找不到检索关联的arel_table 的方法。由于关系是HABTM,因此没有模型可以调用arel_table

我现在有以下内容(有效),但我使用连接表的名称创建了一个新的 arel 表(使用 reflect_on_association 方法检索)。

scope :orphans, lambda {
    teachers = arel_table
    join_table = Arel::Table.new(reflect_on_association(:groups).options[:join_table])

    join_table_condition = join_table.project(join_table[:teacher_id])
    where(teachers[:id].not_in(join_table_condition))
}

这会产生以下 SQL:

SELECT `teachers`.* 
FROM `teachers`    
WHERE (`teachers`.`id` NOT IN (SELECT `groups_teachers`.`teacher_id`  
                               FROM `groups_teachers` ))

那么有没有更好的方法来检索arel_table 而不是创建一个新的?

【问题讨论】:

  • 注意,我认为有一种更简洁的方法可以做到这一点,请参阅下面的答案。

标签: sql ruby-on-rails ruby-on-rails-3 activerecord arel


【解决方案1】:

不幸的是,我相信您的解决方案几乎是目前最干净的解决方案,事实上,关联本身在实例化时在内部执行的操作:

https://github.com/rails/rails/blob/46492949b8c09f99db78b9f7a02d039e7bc6a702/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb#L7

我相信他们使用的反射.join_table 与反射.options[:join_table] 目前仅在 master 中。

【讨论】:

    【解决方案2】:

    如果您知道关联的名称以及连接表(在这种情况下看起来就像您知道的那样),您应该可以调用:

    Arel::Table.new(:groups_teachers)
    

    在我的测试中返回一个 habtm 关联的 Arel 表。感谢this answer 向我指出这一点。

    【讨论】:

    • 至少现在(看看 ARel 3.0.2 和 AR 3.2)你可以做一些丑陋的运动,比如Groups.reflect_on_association(:teachers).through_reflection.klass.arel_table,这应该会给你一个正确绑定的对象。
    • 如果有人感到困惑,请举个例子! User.joins(:sports).where(Arel::Table.new(:sports_users)[:sport_id].eq(SPORT_ID))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多