捞出一个数组的数据
在此前的一家公司测试题中,要实现一个功能,捞出所有用户所在团队 @team
的所有项目@project
发生的动态事件 @events
,我当时写的代码是大概这样的:
def index
@team = current_user.participated_teams.find(params[:team_id])
@projects = @team.projects
@events = @projects.collect{ |project| project.events }.flatten
end
学习完 Ruby on Rails 教程 之后,知道另一种效率更高的底层方法。
类似 Twitter 或者微博的 timeline ,实现的功能是这样的,显示所有 我关注的用户
所发出来的 微博
。
在数据库层面,首先要捞出 我关注的用户
,这个很好办,比如说
@followers = current_user.followers
接下来,要捞出这些用户的所有 微博
。对于每一个关注的用户都有很多微博,@follower.mircoposts
这个的方法是可以的,但是没有 @followers.mircoposts
这样的方法。因为 @followers
是一个数组。
教程中,是这样捞出所有 我关注的用户
所发出来的 微博
的。
def feed
Micropost.where("user_id IN (?) OR user_id = ?", following_ids, id)
end
为了提高效率,还可以使用子查询(subselect),在数据库层查找关注的用户 ID,具体实现方法是
def feed
following_ids = "SELECT following_id FROM relationships WHERE follower_id = :user_id"
Micropost.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id)
end
同理,将我之前的代码重构一下,可以这么写
def index
@team = current_user.participated_teams.find(params[:team_id])
@projects = @team.projects
project_ids = "SELECT project_id FROM projects WHERE team_id = #{@team.id}"
@events = Event.where("project_id IN (#{project_ids})")
end