如何通过 rails 中可能的关系访问 has_many?

How to access has_many through relationship possible in rails?

如何访问我的相关记录?

class Post < ActiveRecord::Base
has_many :post_categories
has_many :categories, through: :post_categories

class Categories < ActiveRecord::Base
has_many :post_categories
has_many :post, through: :post_categories

class PostCategories < ActiveRecord::Base
belongs_to :post
belongs_to :category

PostCategories table 有 id、posts_id 和 categories_id 列。

id | posts_id | categories_id
1. | 2       | 3
2. | 2       | 4

我想要的是:获取与类别相关的帖子。喜欢:x category.

中的所有 Posts where

不确定这是否能解决问题,但在 ActiveRecord 中,您的 Post 将可以直接访问您的 Category 模型,反之亦然。因此,您可以在变量或实例变量中确定您想要的帖子类别,然后查询 @specific_category.posts。如果您在控制器中执行此操作,您甚至可以在 before_action 过滤器中执行此操作。如果您在序列化程序中使用它,则差别不大。

您还可以在 Post 模型中创建范围并使用活动记录或原始 SQL 来查询特定参数。

您的 Category 模型也有错误。有很多总是复数所以它会是 has_many :posts, through: :post_categories

是的,这很简单。

one_or_more_categories = # Category.find... or Category.where...
posts = Post.joins(:categories).where(category: one_or_more_categories)

Rails 足够聪明,可以采用模型或查询 找到一些数据并将其转换为有效的适当查询,这可能是子查询.在 Rails 控制台 (bundle exec rails c) 中进行尝试是查看生成的 SQL 并更好地了解正在发生的事情的好方法。

(编辑:正如另一个答案所指出的,如果您已经检索到一个特定的类别实例,那么您可以只引用 category.posts 并直接处理该关系,包括链接 .order.limit 和 so-on).

另一种写法 'lower level' 是:

Post.joins(:categories).where(category: {id: one_or_more_category_ids})

...这本质上就是 Rails 在给定 ActiveRecord 模型实例或 ActiveRecord::Relation 时在幕后所做的事情。如果您已经知道例如类别“名称”,或您可以搜索的其他一些索引文本列,然后相应地调整上面的内容:

Post.joins(:categories).where(category: {name: name_of_category})

joinswhere 的模式采用哈希,其中连接 table 名称用作键,值嵌套在该哈希下,可以根据需要采用任意深度(例如,如果类别 had-many 子类别),您可以在 Rails 指南或适当的网络搜索中找到更多相关信息。唯一的问题是曲折的 singular/plural 东西,Rails 用来尝试让事情变得更“English-y”,但有时 - 就像在这种情况下 - 只会产生额外的认知负担,需要记住哪些部分应该是单数,哪些应该是复数。

获取类别对象,可以直接获取相关的post。请看以下内容

category = Category.find(id)
posts = category.posts

由于您已经配置了 has_many_through 关系,rails 将获取 post 条与类别相关的记录。