Has_and_belong_to_many 协会
Has_and_belong_to_many association
我有两个模型,它们之间没有关联。所以,我生成了一个迁移并添加了一个关联。
class Post < ActiveRecord::Base
has_and_belongs_to_many :workspaces
end
class Workspace < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class CreateJoinTablePostsUsers < ActiveRecord::Migration
def change
create_join_table :posts, :workspaces do |t|
# t.index [:post_id, :workspace_id]
# t.index [:workspace_id, :post_id]
end
end
end
我目前有一个显示所有 post 的页面。但是,我在post创建表单中添加了一个multi select,以便在创建时select一个或多个工作空间。我希望能够仅显示为该特定工作区创建的 post,而不是像目前那样显示所有这些。
我的控制器如下:
class PostsController < Admin::BaseControlle
def index
respond_to do |format|
format.html
format.json do
@posts = Post.all.order(:order)
render json: present_collection(@posts, PostPresenter).map(&:as_json)
end
end
end
private
def post_params
params.require(:post).permit(:label, :url, :active, workspace_ids: [])
end
end
我可以通过这种方式获取关联的工作空间:
Post.first.workspaces
但我想显示所有 posts,当我尝试这个命令时出现错误:
Post.all.workspaces
我怎样才能改变我的控制器并实现它?预先感谢您的帮助!
好吧,你应该有一个 table
按照 rails 约定称为 PostsWorkspaces
这样你应该能够做这样的事情:
posts_in_workspaces = PostsWorkspaces.all.pluck(:post_id)
Posts.where(id: posts_in_workspaces )
以上将 return 至少有一个 workspace
关联的 posts
,方法 Post.all.workspaces
的问题是并非所有帖子都需要有一个相关的工作空间(或多个),你也可以考虑 Post.all
比如 select * from posts
这不是你想要完成的。
希望以上内容对您有所帮助!
你想错了。 Post.first.workspaces
有效,因为关联应用于返回的 Post
实例。但是Post.all
returns一个集合。
您最好的选择是执行以下操作。
# Return all posts that have a workspace associated
posts = Post.joins(:workspaces).all.distinct
posts.each do |post|
post.workspaces
end
如果您想包含没有工作区的帖子
posts = Post.includes(:workspaces).all
posts.each do |post|
post.workspaces
end
我有两个模型,它们之间没有关联。所以,我生成了一个迁移并添加了一个关联。
class Post < ActiveRecord::Base
has_and_belongs_to_many :workspaces
end
class Workspace < ActiveRecord::Base
has_and_belongs_to_many :posts
end
class CreateJoinTablePostsUsers < ActiveRecord::Migration
def change
create_join_table :posts, :workspaces do |t|
# t.index [:post_id, :workspace_id]
# t.index [:workspace_id, :post_id]
end
end
end
我目前有一个显示所有 post 的页面。但是,我在post创建表单中添加了一个multi select,以便在创建时select一个或多个工作空间。我希望能够仅显示为该特定工作区创建的 post,而不是像目前那样显示所有这些。 我的控制器如下:
class PostsController < Admin::BaseControlle
def index
respond_to do |format|
format.html
format.json do
@posts = Post.all.order(:order)
render json: present_collection(@posts, PostPresenter).map(&:as_json)
end
end
end
private
def post_params
params.require(:post).permit(:label, :url, :active, workspace_ids: [])
end
end
我可以通过这种方式获取关联的工作空间:
Post.first.workspaces
但我想显示所有 posts,当我尝试这个命令时出现错误:
Post.all.workspaces
我怎样才能改变我的控制器并实现它?预先感谢您的帮助!
好吧,你应该有一个 table
按照 rails 约定称为 PostsWorkspaces
这样你应该能够做这样的事情:
posts_in_workspaces = PostsWorkspaces.all.pluck(:post_id)
Posts.where(id: posts_in_workspaces )
以上将 return 至少有一个 workspace
关联的 posts
,方法 Post.all.workspaces
的问题是并非所有帖子都需要有一个相关的工作空间(或多个),你也可以考虑 Post.all
比如 select * from posts
这不是你想要完成的。
希望以上内容对您有所帮助!
你想错了。 Post.first.workspaces
有效,因为关联应用于返回的 Post
实例。但是Post.all
returns一个集合。
您最好的选择是执行以下操作。
# Return all posts that have a workspace associated
posts = Post.joins(:workspaces).all.distinct
posts.each do |post|
post.workspaces
end
如果您想包含没有工作区的帖子
posts = Post.includes(:workspaces).all
posts.each do |post|
post.workspaces
end