在 Rails 中按组获取帖子

Get posts by group in Rails

在我的应用程序中,我有属于群组的用户并且可以创建帖子。

在每个群组页面上,我试图显示该特定群组中用户的所有帖子(从最新到最旧)。这是我到目前为止尝试过的代码,但它显示了每个用户的所有帖子,无论用户属于哪个组。

这是groups_controller.rb

class GroupsController < ApplicationController
  def show
    @group = Group.find(params[:id])
    if logged_in?
      @feed_items = Post.latest_posts_by_group(@group)
    end
  end
end

post.rb中:

class Post < ActiveRecord::Base
  belongs_to :user

  def self.latest_posts_by_group(group_id)
    Post.find_by_sql(['select posts.*
      from groups
      inner join users
      on users.group_id = groups.id
      inner join posts
      on posts.user_id = user_id
      where groups.id = ?
      order by created_at desc', group_id])
  end
end

user.rb(好吧,至少是联想):

class User < ActiveRecord::Base
  belongs_to :group
  has_many :posts
end

group.rb(同样,仅显示关联):

class Group < ActiveRecord::Base
  has_many :users
end

你可以用示波器做到这一点。加入:user协会,对users.group.id提出条件。下面的代码应该可以做到。

class Post < ActiveRecord::Base
  belongs_to  :user
  has_one :group, through: :user

  scope :latest_posts_by_group, ->(group) {
    joins(:user).
    where(users: {group_id: group.id}).
    reorder(created_at: :desc)
  }
end

这会创建一个像这样的 SQL:

SELECT posts.* FROM posts
  INNER JOIN users ON users.id = posts.user_id
WHERE users.group_id = ?
ORDER BY posts.created_at DESC

如果你愿意,也可以把groupstable也考虑进去。但这不是必需的,因为您在 users table.

中有 group_id
class Post < ActiveRecord::Base
  belongs_to  :user
  has_one :group, through: :user

  scope :latest_posts_by_group, ->(group) {
    joins(:group).
    where(groups: {id: group.id}).
    reorder(created_at: :desc)
  }
end

这会创建一个像这样的 SQL:

SELECT posts.* FROM posts
  INNER JOIN users ON users.id = posts.user_id
  INNER JOIN groups ON groups.id = users.group_id
WHERE groups.id = ?
ORDER BY posts.created_at DESC

查看 Rails Guides 了解更多详情。

我会使用 rails 内置的关联助手,而不是手动构建 SQL 查询。在这种情况下

class  Post < ActiveRecord::Base
  belongs_to :user
  has_one :group, through: :user

class  User < ActiveRecord::Base
  belongs_to :group
  has_many :posts

class  Group < ActiveRecord::Base
  has_many :users
  has_many :posts, through: :users

当您正确构建这些关联时,rails 会自动为您生成 @group.posts 等方法。

您应该注意,但是必须以某种方式命名外键才能使关联起作用,但是从您的 SQL 查询中我看到您已经通过命名外键 group_iduser_id 分别在 UsersPosts 表中。

进一步参考:http://edgeguides.rubyonrails.org/association_basics.html#the-has-many-through-association