如果我有这种关系:
Foo has_many :bars
Bar belongs_to :foo
我想在Foo
模型中指定一个范围,因为我想要过滤一些字段(即where("code='AV1' OR code='AH5'"
)
bars
中包含Foo
的外键。如何指定适合上述过滤器的bars
?像Bar.foo.customScope
之类的东西,让我们说我想过滤Bar
中的某些东西?
Bar.where(".....").foo.customScope
?
修改
是的,代码是foo表中的一个字段
我在bars
表中有几百个条目。它们中的每一个都有foos
表(模型Foo
)的外键。我想从bars
表中获取具有特定code
的所有foos
的列表。 E.g。
foos:
id, code
1,okay
2,not okay
3,somewhat okay
bars:
id,foo_id,otherstuff
1,1,blah
2,1,blob
3,2,hello
4,3,hurray
如果我的Foo模型如下:
class Foo < ActiveRecord::Base
has_many :bars
def self.goodCodes
where("code='okay' or code='somewhat okay')
end
end
我的Bar模型如下所示:
class Bar < ActiveRcord::Base
belongs_to :foo
end
我想调用一些东西来获取符合条件的所有Bar
项以及满足foos
条件的goodCodes
项。我认为它会是这样的:Bar.where(....).foo.goodCodes
或者
Bar.where(...).each do |row|
if row.foo.goodCodes
##do something
end
end
答案 0 :(得分:1)
一定有些困惑。由于Bar
属于1且仅{1} foo
,因此运行@bar.foo
只会返回1个结果:foo
您已分配给@bar
。范围用于返回多个记录。
如果您拥有Foo
模型中提到的范围:
class Foo < ActiveRecord::Base
scope :customScope, -> { where("code='AV1' OR code='AH5'") }
end
然后customScope
范围是Foo
类的一个类方法:
Foo.customScope # e.g. => [#<Foo code='AV1'], ...]
但是如果范围在Bar
类:
class Bar < ActiveRecord::Base
scope :customScope, -> { where("code='AV1' OR code='AH5'") }
end
然后拨打Bar.customScope
并返回符合该条件的所有bars
。您也可以将其调用以获取Foo
bars
的子集:
foo = Foo.new
foo.bars << Bar.new(code: 'AV1')
foo.bars << Bar.new(code: 'XXX')
foo.bars # => [#<Bar code: 'AV1'>, #<Bar code: 'XXX'>]
foo.bars.customScope # => [#<Bar code: 'AV1'>]
当你说:
时,要澄清任何困惑我想在Foo模型中指定一个范围,因为有一些范围 我希望过滤的字段(即where(&#34; code =&#39; AV1&#39; OR) 代码=&#39; AH5&#39;&#34)
我认为code
是Foo
中的字段。但后来你说:
如何指定适合上述过滤器的条形图?
嗯,你不能。如果code
字段位于Foo
表中,则该过滤器只能用于Foo
模型。您无法通过其他数据库表中的字段过滤Bar
。但是,您可以获取与过滤器或范围Foo
匹配的所有Foo.customScope
,然后获取所有foo
s bar
s:
Foo.customScope.flat_map &:bars
此外,没有这样的方法Bar.foo
。 Bar
是一个类,只有Bar
的实例才会回复foo
:
Bar.foo # NoMethodError
bar = Bar.new
bar.foo = Foo.new
bar.foo # the new foo
更新:
这不会起作用:
row.foo.goodCodes
因为goodCodes
是Foo上的类方法,而不是row.foo
等实例。就像我上面说的那样,你需要这样做:
Foo.customScope.flat_map &:bars
获取bar
匹配条件的所有foo
。
原因是当您获得Bar
的实例时,例如:
Bar.where(...).each do |row|
if row.foo.goodCodes
##do something
end
end
row
现在是Bar的实例。 row.foo
将返回foo
的实例。 您无法在实例上调用范围或类方法 。这不会起作用:row.foo.goodCodes
,因为您将goodCodes
定义为Foo的类方法。如前所述,您可以致电:
foos_with_good_codes = Foo.goodCodes
bars_with_foos_that_have_good_codes = foos_with_good_codes.flat_map &:bars
希望能稍微清理一下。