【问题标题】:How do you query upstream in a polymorphic association without raw SQL?在没有原始 SQL 的情况下,如何在多态关联中查询上游?
【发布时间】:2013-03-13 06:27:20
【问题描述】:

在我的锻炼应用中,用户可以“检查”一个锻炼来完成它。如果我知道 checkable_type 是 'Exercise' 并且有 checkable_id,我该如何查询练习名称?

我不确定要在我的控制器中添加什么以根据 checkable_type 和 id 列出“已完成的练习”及其名称。

class Exercise < ActiveRecord::Base
    attr_accessible :name 
    has_many :checks, :as => :checkable
end

class Check < ActiveRecord::Base
    belongs_to :checkable, :polymorphic => true
    attr_accessible :checkable, :checkable_id, :checkable_type
end

【问题讨论】:

    标签: ruby-on-rails activerecord polymorphic-associations


    【解决方案1】:

    只是加入另一个模型会给你想要的吗?

    completed_exercises = Exercise.joins(:checks)
    

    这应该会产生一个内连接,并且 AR 已经知道如何将多态关联作为查询的一部分。

    【讨论】:

    • 不完全 - 这会拉出所有已完成练习的列表,但它不会显示您何时完成以及是否多次完成。我怎样才能做类似 completed_exercises = Check.joins(:exercises) 的事情?这样我就可以在每次有人完成时提取练习的名称和 created_at?
    • 在这种情况下,我会翻转它并从检查开始。类似于 swap.nil 的答案。只需确保包含练习关联,这样当您遍历 check.exercise 时,它​​就不会触发 N+1 查询。
    【解决方案2】:

    你可以定义一个范围checkable_type

    scope :checkable_type, lambda { |class_name| where("checkable_type = ?", class_name) }
    

    我猜你想要'Exercise' 类型的多态记录,并且只有在练习完成后才会创建,或者你可以在completed_at 时间戳列中维护它。

    然后您可以拉出所有已完成练习的列表

    scope :completed, where('completed_at IS NOT NULL')
    
    completed_exercises = Check.checkable_type('Exercise').completed
    

    如果不是这样,您可以忽略 completed 范围

    【讨论】:

      【解决方案3】:

      想通了!

      class Exercise < ActiveRecord::Base
        attr_accessible :exercise_name
        has_many :checks, as: :checkable
      end
      
      class Check < ActiveRecord::Base
        belongs_to :checkable, polymorphic: true
        attr_accessible :checkable_id, :checkable_type, :exercise_name
      end
      

      我意识到我需要先调用 .checkable,然后再调用练习模型中的所需属性。

      <% @checks.each do |check| %>
        <%= check.checkable.exercise_name %>
        <%= check.checkable.created_at %>
      <% end %>
      

      这会从练习表中提取正确的练习名称和“完成时间”(通过 created_at)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-16
        • 1970-01-01
        • 2020-08-09
        相关资源
        最近更新 更多