[英]Rails scope by absence of has_one polymorphic association
I have records that, instead of being deleted, are invalidated by creating an entry in a polymorphic record_invalidations table. 我有记录,而不是被删除,而是通过在多态record_invalidations表中创建一个条目来使记录无效。
The setup looks like this: 设置如下所示:
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
(There are multiple record classes, hence the polymorphic relation.) (有多个记录类,因此是多态关系。)
Question: How do I make a scope, that returns records based on the absence of entries in another class pointing back at the class in question. 问:我如何做一个范围,返回基于在有关类别回指向另一个类没有条目记录。
The current code does not work because the relation pointer is in the records_invalidations table, not the records table. 当前代码不起作用,因为关系指针位于records_invalidations表中,而不是在records表中。
UPDATE 2 更新2
The record_invalidation class matches the table name just fine, I think the problem is the column name. record_invalidation类与表名匹配就好了,我认为问题是列名。 Here's the (simplified) schema: 这是(简化的)模式:
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
UPDATE 3 更新3
I see know why the first error was happening, so I removed that update. 我知道知道为什么会发生第一个错误,因此我删除了该更新。 Now I am passing the correct table name that I am joining in the SQL query, but I have a number of arguments mismatch. 现在,我传递了要在SQL查询中加入的正确表名,但是我有许多参数不匹配。 Can I pass another argument to the where clause? 我可以将另一个参数传递给where子句吗?
self.joins(:invalidation).where('record_invalidations.id is null')
Gives: 得到:
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
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 感谢Rails作用域检查关联是否不存在
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. 如果有人有更好的解决方案,请随时添加,我会接受,而不是我自己的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.