tl;dr使用
Org.includes(:posts).where(posts: {category: :job})
更长的答案...
我想值得注意的是,你的问题实际上与enums
没有任何关系。也不涉及“包含另一个模型”。你真正想做的是指定连接表上的条件,你可以在Active Record查询接口指南中了解更多信息。
问题在于你的ActiveRecord查询语句格式不正确:
Org.includes(:posts).where(category: Post.categories[:job])
您目前所拥有的基本形式是:
。
Model.where(attribute: 'value')
这个:
.includes(:joined_models)
这段代码对基本形式没有改变。因此,ActiveRecord
将返回所有Model
记录,其中attribute
具有value
。或者,在您的情况下,返回所有category
为job
的Org
模型。
但这不是您想要的。您想要所有拥有Posts
的Orgs
,其中Post
category
是job
。(或者,我想说的是,“所有带有职位帖子的Orgs。”)
这就是.includes(:joined_models)
部分发挥作用的地方:它允许您在joined_models
上指定条件,其基本形式如下:
Model.includes(:joined_models).where(joined_models: {attribute: 'value'})
^^^^^^^^^^^^^
或者,在你的情况下:
Org.includes(:posts).where(posts: {category: Post.categories[:job]})
或者,就像mu在评论中说的那样:
Org.includes(:posts).where(posts: {category: :job})
现在,我不知道你处于什么样的上下文环境中,但是无论你身处何处,上述代码都要求你的上下文环境对
Org
有很多了解,并且知道它与
Post
的关系以及
Post
的属性,这通常并不好。因此,我建议你在
Org
中添加一个方法,使你能够将对
Org
的了解与你的上下文环境分离开来:
class Org < ApplicationRecord
class << self
def with_job_posts
includes(:posts).where(posts: {category: :job}})
end
end
end
现在你只需要简单地执行:
Org.with_job_posts
我希望你能翻译以下内容: "...and get back "all Orgs with job posts". And your context needs to know a lot less about Post
and its attributes."
Post
还有一个类别是 conference
。所以,你可以这样做:
class Org < ApplicationRecord
class << self
def with_job_posts
includes(:posts).where(posts: {category: :job}})
end
def with_conference_posts
includes(:posts).where(posts: {category: :conference}})
end
end
end
但是,如果您的帖子
类别
开始增多,那么这将变得很繁琐。因此,建议采用以下方式:
class Org < ApplicationRecord
Post.categories.each do |post_category|
define_singleton_method("#{post_category}"_posts) do
includes(:posts).where(posts: {category: post_category.to_sym})
end
end
end
现在您将拥有任意数量的方法,例如:
Org.with_job_posts
Org.with_conference_posts
Org.with_some_other_type_of_posts
太棒了!查看这个问答以获取来自Jörg W Mittag的更多信息。
顺便说一下,那似乎是使用enum
的潜在不同寻常的方式。在文档中,它说:
最后,也可以使用哈希明确映射属性和数据库整数之间的关系:
class Conversation < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end
我一直认为映射枚举应该使用整数作为值,而不是字符串。有趣。
Org.includes(:posts).where(posts: {category: :job})
,是吗?我经常使用枚举字符串,这样在ActiveRecord外部理解起来会更容易。 - mu is too short