我有三个具有多态关系的模型如下:
class DataSource < ActiveRecord::Base
belongs_to :sourceable, polymorphic: true
end
class Foo < ActiveRecord::Base
has_many :data_sources, as: :sourceable
# For the sake of this example, I have place the scope here.
# But I am going to put it in a Concern since Baz needs this scope as well.
scope :bar_source_id, -> (id) do
joins(:data_sources)
.where(data_sources: { source: 'bar', source_id: id })
.first
end
end
class Baz < ActiveRecord::Base
has_many :data_sources, as: :sourceable
end
我希望能够根据相关Foo
的{{1}}找到source_id
条记录。换句话说,DataSource
应该返回Foo.bar_source_id(1)
条记录Foo
包含data_sources
的记录。但是source: 'bar', source_id: 1
模型的范围不能像我预期的那样工作。
Foo
会返回正确的Foo.bar_source_id(1)
记录,但如果没有Foo
DataSource
source_id
1
则会返回。
另一方面,如果没有记录,Foo.all
将始终返回正确的记录或Foo.joins(:data_sources).where(data_sources: { source: 'bar', source_id: 1 }).first
。这是我期望的行为。
为什么当我从模型本身调用它时,这个查询是否有效,但是当我将它作为范围包含在模型中时却不行?
编辑:
我对我的问题有部分答案。范围中的nil
导致第二个查询加载所有.first
条记录。如果我删除Foo
,我将返回.first
。
为什么ActiveRecord_Relation
在这两种情境中表现不同?
答案 0 :(得分:0)
在挖掘之后我发现了这个:ActiveRecord - "first" method in "scope" returns more than one record
我认为这里的基本原理是scope
并不意味着返回单个记录,而是返回记录集合。
我可以通过添加方法bar_source_id
而不是使用范围来获得我需要的结果。
def self.bar_source_id(id)
joins(:data_sources)
.where(data_sources: { source: 'bar', source_id: id })
.first
end