【问题标题】:How to merge polymorphic results of a child and parent together with a has_many association?如何将孩子和父母的多态结果与 has_many 关联合并在一起?
【发布时间】:2017-05-06 06:54:09
【问题描述】:

我有 3 个模型,分别名为 User、Photo 和 Report

模型Report 是一个多态类,用于报告用户和照片,模型User 与模态Photo 具有多态关联。

所以功能是用户可以报告照片或任何其他用户。

下面是Report的迁移文件。

class CreateReports < ActiveRecord::Migration
  def change
    create_table :reports do |t|
      t.integer :user_id
      t.integer :reported_id
      t.string :reported_type, default: "User"
      t.string :note, default: ""
    end
 end
end

以下是关联

class User < ActiveRecord::Base
  ...
  has_many :photos, as: :attachment
  has_many :reports, dependent: :destroy
  ...
end

class Photo < ActiveRecord::Base
  ...
  belongs_to :attachment, :polymorphic: true
end

class Report < ActiveRecord::Base
  belongs_to :user
  belongs_to :reported, polymorphic: true
end

目前我使用如下查询来获取用户自己或他们的照片报告的用户列表。

 Report.where("(reported_id=? AND reported_type=?) OR (reported_id in (?) AND reported_type=?)", 
  self.id, "User", self.photos.pluck(:id), "Photo")

所以,我想知道如何通过 has_many 关联实现相同的目标?

如果我有任何更好的方法可以达到同样的效果,请帮助我,如果我错了,请纠正我。

【问题讨论】:

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


    【解决方案1】:

    Rails 足够聪明,可以通过多态关联使用参数的类进行过滤。你可以用一种非常简单的方式重写你的条件:

    Report.where(reported: [self] + self.photos)
    
    # result sql
    SELECT  "reports".* 
    FROM "reports" 
    WHERE (
      ("reports"."reported_type" = 'User' AND "reports"."reported_id" = 1) OR 
      ("reports"."reported_type" = 'Photo' AND "reports"."reported_id" IN (1, 2))
    ) 
    

    此代码仅适用于 Rails 5.x。

    更新

    在 Rails 4.2 中,此代码不起作用。您可以查看相关的 SO 问题:Finding record where polymorphic association or nilOR operator in WHERE clause with Arel in Rails 4.2

    我认为,您当前的代码是 Rails 4.2 中最好的代码

    【讨论】:

    • 感谢您的输出,但这个返回查询对我来说是这样的SELECT reports.* FROM reports` WHERE reports.reported_type = 'User' AND reports.reported_id IN (273, 932, 1215, 1216, 1217)` 我猜只有用户从中挑选。
    • 你使用的是什么版本的 Rails?
    • 我正在使用 rails 4.2.4
    猜你喜欢
    • 2011-08-29
    • 2020-12-11
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 1970-01-01
    相关资源
    最近更新 更多