tl;dr 使用
Org.includes(:posts).where(posts: {category: :job})
更长的答案...
我想值得注意的是,您的问题与enums 没有任何关系。它也与“包括另一个模型”无关。您真正想做的是Specify Conditions on the Joined Tables,您可以在Active Record Query Interface guide 中了解更多信息。
问题是您的 ActiveRecord 查询格式错误:
Org.includes(:posts).where(category: Post.categories[:job])
你目前拥有的基本形式是:
Model.where(attribute: 'value')
:
.includes(:joined_models)
...bit 不会改变基本形式。因此,ActiveRecord 将返回所有Model 记录,其中attribute 具有value。或者,在您的情况下,所有Org 模型,其中category 是job。
但是,这不是你想要的。您想要所有具有Posts 的Orgs,其中Post category 是job。 (或者,我想,“所有有职位的组织。”)
.includes(:joined_models) 位出现在哪里:它允许您在 joined_models 上指定条件,其基本形式如下:
Model.includes(:joined_models).where(joined_models: {attribute: 'value'})
^^^^^^^^^^^^^
或者,在你的情况下:
Org.includes(:posts).where(posts: {category: Post.categories[:job]})
或者,正如 mu 在 cmets 中所说:
Org.includes(:posts).where(posts: {category: :job})
现在,我不知道你在什么上下文中,但无论你在哪里,上面的代码都要求你的上下文了解很多关于Org 以及它与Post 的关系以及@987654350 的属性@ 这通常不是很好。所以,我建议你给Org添加一个方法,让你在你的上下文中解耦Org的知识:
class Org < ApplicationRecord
class << self
def with_job_posts
includes(:posts).where(posts: {category: :job}})
end
end
end
现在你可以简单地做:
Org.with_job_posts
...并取回“所有有工作职位的组织”。而且您的上下文需要对Post 及其属性知之甚少。
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
但是,如果您的Post categories 开始增长,那将变得乏味。所以,改为:
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
太棒了!查看this Q&A 以获取来自Jörg W Mittag 的更多信息。
顺便说一句,这看起来像是使用enum 的一种可能不寻常的方式。在docs 中,它说:
最后,还可以使用哈希显式映射属性和数据库整数之间的关系:
class Conversation < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end
我一直认为映射枚举旨在使用整数作为值,而不是字符串。很有趣。