1

我有一些记录,而不是被删除,而是通过在多态 record_invalidations 表中创建一个条目而无效。

设置如下所示:

class RecordInvalidation < ActiveRecord::Base
  belongs_to :archivable, polymorphic: true
end


class Record < ActiveRecord::Base
  has_one :invalidation, class_name: "RecordInvalidation", as: :archivable

  def self.default_scope
    where(invalidation: nil)
  end
end

(有多个记录类,因此是多态关系。)

问题:如何创建一个范围,它根据另一个类中没有指向相关类的条目来返回记录。

当前代码不起作用,因为关系指针位于 records_invalidations 表中,而不是 records 表中。

更新 2

record_invalidation 类与表名匹配得很好,我认为问题出在列名上。这是(简化的)架构:

create_table "records", force: :cascade do |t|
  t.text     "content",        null: false
end

create_table "record_invalidations", force: :cascade do |t|
  t.integer  "archivable_id"
  t.string   "archivable_type"
end

更新 3

我知道为什么会发生第一个错误,所以我删除了该更新。现在我传递了我在 SQL 查询中加入的正确表名,但我有许多参数不匹配。我可以将另一个参数传递给 where 子句吗?

self.joins(:invalidation).where('record_invalidations.id is null')

给出:

ActiveRecord::StatementInvalid: PG::ProtocolViolation: ERROR:  bind 
message supplies 1 parameters, but prepared statement "a56" requires 2

: SELECT  "records".* FROM "records" 
    INNER JOIN "record_invalidations" ON 
    "record_invalidations"."archivable_id" = "records"."id" AND 
    "record_invalidations"."archivable_type" = $1 WHERE 
    (record_invalidations.id is null) AND "plans"."id" = $2 LIMIT 1
4

1 回答 1

0

This may not be the most efficient way, but it works:

def self.default_scope
  # Only show records that were not invalidated
  # Makes a list of all invalidated record ids in a subquery then checks for id
  where.not(:id => RecordInvalidation.select(:archivable_id)
                                     .where(archivable_type: self.name)
                                     .uniq)
end

Thanks to rails scope to check if association does NOT exist

I just added the required filtering for the polymorphic association to that answer.

If anyone has a better solution feel free to add and I will accept that instead of my own.

于 2015-09-11T18:10:45.780 回答