tl; др использовать
Org.includes(:posts).where(posts: {category: :job})
Более длинный ответ ...
Я думаю, стоит отметить, что ваш вопрос не 'на самом деле не имеет ничего общего с enums
. Это также не связано с «включением другой модели». Что вы действительно пытаетесь сделать, это Укажите условия для объединяемых таблиц , о которых вы можете прочитать в руководстве по интерфейсу запроса Active Record .
Проблемычто вы исказили свой запрос ActiveRecord:
Org.includes(:posts).where(category: Post.categories[:job])
Основная форма того, что у вас сейчас есть:
Model.where(attribute: 'value')
The:
.includes(:joined_models)
.. .bit не меняет существенную форму. Итак, ActiveRecord
вернет все Model
записей, где attribute
имеет value
. Или, в вашем случае, все Org
модели, где category
равно job
.
Но это не то, что вы хотите. Вы хотите, чтобы все Orgs
имели Posts
, где 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]})
Или, как говорит му в комментариях:
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
... и вернуть "все организации с должностями". И ваш контекст должен знать намного меньше о 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
Super! Проверьте этот Q & A для получения дополнительной информации от Jörg W Mittag .
BTW, который выглядит как потенциально необычный способ использования enum
. В документах написано:
Наконец, также можно явно отобразить связь между атрибутом и целым числом базы данных с помощью хеша:
class Conversation < ActiveRecord::Base
enum status: { active: 0, archived: 1 }
end
Я всегда полагал, что отображаемое перечисление должно было использовать целые числа в качестве значений, а не строки. Интересно.