假设有两种模型:User和Post,其中每个帖子属于一个用户,并且一个用户可以有许多帖子。如果你做了@user.posts,你会得到@user的所有帖子。但是,给定@users,是否有比Post.where(user_id: @users.map(&:id))更优雅的方法来获取@users的所有帖子?比如@users.posts?
User
Post
@user.posts
@user
@users
Post.where(user_id: @users.map(&:id))
@users.posts
unhi4e5o1#
根据您对@users是ActiveRecord::Relation的评论,最简单的方法是让Active Record为您解决:
ActiveRecord::Relation
Post.where(user: @users) # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN # (SELECT "user"."id" FROM "users")
这将执行单个数据库查询,并让数据库通过子选择完成所有繁重的工作(您的子选择可能看起来不同...在我例子中,@users简单地是User.all)。对于不使用.map获取id字段的情况,可能需要考虑使用.pluck从数据库返回一个数组值,而不获取整个记录。例如:
User.all
.map
.pluck
@users.pluck(:name) # instead of @users.map(&:name)
理论上,您可以在您的场景中使用.pluck,但如果您有很多用户,您将生成并发送包含用户ID数组的非常长的SQL查询,而不是让数据库自己完成工作。
Post.where(user_id: @users.pluck(:id)) # SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN # (2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 64, 65, 66, 67, 68, 69, 70, 72, 73, 71, 74, 75, 76, 77, 78, 79, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100, 101, 102, 103, 97)
1条答案
按热度按时间unhi4e5o1#
根据您对
@users
是ActiveRecord::Relation
的评论,最简单的方法是让Active Record为您解决:这将执行单个数据库查询,并让数据库通过子选择完成所有繁重的工作(您的子选择可能看起来不同...在我例子中,
@users
简单地是User.all
)。对于不使用
.map
获取id字段的情况,可能需要考虑使用.pluck
从数据库返回一个数组值,而不获取整个记录。例如:理论上,您可以在您的场景中使用
.pluck
,但如果您有很多用户,您将生成并发送包含用户ID数组的非常长的SQL查询,而不是让数据库自己完成工作。