我有一个带有复杂联接的模型:
class Submission < ApplicationRecord
has_many :histories,
->(s) { where(/* A complex query */) },
class_name: 'SubmissionFieldHistory'
end
我希望该范围查询替换由ActiveRecord生成的默认条件,但是似乎将添加到条件中。
有一种简单的说法has_many :histories, :but_join_it_how_i_say
吗?
答案 0 :(得分:1)
如果使用“默认条件”,则表示默认SQL条件WHERE HISTORIES_TABLE.submission_id = SOME_SUBMISSION_ID
。
要为has_many
指定自定义查询,请使用unscope
:
class Submission < ApplicationRecord
has_many :histories,
->(s) { unscope(:where).where(/* A complex query */) },
class_name: 'SubmissionFieldHistory'
end
上面的 unscope(:where)
将删除链中的任何/所有先前的WHERE
SQL查询,其中之一包括默认的WHERE HISTORIES_TABLE.submission_id = SOME_SUBMISSION_ID
,这是您想要的删除。
submission = Submission.find(1)
submission.histories
# SubmissionFieldHistory Load (5.5ms) SELECT "submission_field_histories".* FROM "submission_field_histories"
# WHERE /* A complex query */ LIMIT $1 [["LIMIT", 11]]
但是,由于unscope(:where)
删除了所有先前的WHERE
条件,因此它也会同时删除default_scope
提供的条件(如果您在{{1}中有default_scope
}。为了也使其适用于SubmissionFieldHistory
,您可以使用更具体的default_scope
,如下所示:
app / models / submission_field_history.rb
unscope(where: SOME_ATTRIBUTE)
app / models / submission.rb
class SubmissionFieldHistory < ApplicationRecord
# example: (default to not fetching anymore "deleted" records)
default_scope { where(is_deleted: false) }
belongs_to :submission
end
class Submission < ApplicationRecord
has_many :histories,
->(s) { unscope(where: :submission_id).where(/* A complex query */) },
class_name: 'SubmissionFieldHistory'