在Ruby on Rails中从数据库预加载数据

时间:2012-05-17 15:19:27

标签: ruby-on-rails ruby

我正在尝试做这样的事情来预加载所有数据,所以每次循环运行时我都不需要进行数据库调用。

# Get all data and do some eager loading
bets = Bet.find(:all, :include => :team_id)

games = Game.find(:all)

games.each do |game|
  bets.find_all_by_user_id(user.id) # Now I want to get the specific bets, but I can't do  find() on the returned array
end

和我试过的另一种方式

bets = Bet.where(:user_id => users) # users are an array of ID's

games = Game.find(:all)

games.each do |game|
  bets.find_all_by_user_id(user.id) # This works, but it makes a db call every time, which makes the site really slow.
end

所以基本上我要做的是加载所有数据,然后在循环中使用它而不必联系数据库。最好的办法是什么?

2 个答案:

答案 0 :(得分:2)

您可能必须在之前的某个时间点进行调用,将数据保存在变量中,然后在循环中访问该变量。像这样:

games = Game.all

bets = Bet.all

games.each do |game|
    bets.select {|b| b.user_id == user.id}
end

不要在数组中使用finder方法:如果这样做,你将再次查询数据库。坚持使用Ruby enumerable methods来处理您已有的数据。

答案 1 :(得分:1)

我不确定你想做什么......你从哪里得到用户变量。为什么你需要在每场比赛中显示所有投注?所以,我希望你的投注属于用户并发布到一些游戏。您需要列出用户参与的每个游戏的所有投注吗?所以,用户应该是:

has_many :bets    
has_many :games, :through => :bets

现在:

user.games.all( :include => :bets ).each do |game|
  game.bets # will be already loaded
end

下面: :include - 应该加载的名称关联。命名的符号引用已定义的关联。 - 引自Rails API