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

时间:2022-08-07 15:15:58

I'm trying to do something like this to preload all data, so I don't have to a database call every time the loop runs.

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

# 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

and the other way I've tried

和我试过的另一种方式

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

So basically what I'm trying to do is to load all data, and then use it in the loop without having to contact the database. What is the best approach to this?

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

2 个解决方案

#1


2  

You'll probably have to make the call at some previous point, save the data in a variable, and then access that variable in the loop. Something like this:

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

games = Game.all

bets = Bet.all

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

Don't use finder methods inside the array: if you do, you'll query the database again. Stick with the Ruby enumerable methods to act on the data you already have.

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

#2


1  

I'm not sure what are you trying to do... Where did you get user variable. Why did you need to show all bets in each game? So, I'm hoping that your Bet belongs to User and posted to some Game. And you need to list all Bets for each Game that User had participated at? So, in user should be:

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

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

And now:

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

Here: :include - Names associations that should be loaded alongside. The symbols named refer to already defined associations. - quote from Rails API.

这里:: include - 命名应该加载的关联。命名符号表示已定义的关联。 - 来自Rails API的引用。

#1


2  

You'll probably have to make the call at some previous point, save the data in a variable, and then access that variable in the loop. Something like this:

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

games = Game.all

bets = Bet.all

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

Don't use finder methods inside the array: if you do, you'll query the database again. Stick with the Ruby enumerable methods to act on the data you already have.

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

#2


1  

I'm not sure what are you trying to do... Where did you get user variable. Why did you need to show all bets in each game? So, I'm hoping that your Bet belongs to User and posted to some Game. And you need to list all Bets for each Game that User had participated at? So, in user should be:

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

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

And now:

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

Here: :include - Names associations that should be loaded alongside. The symbols named refer to already defined associations. - quote from Rails API.

这里:: include - 命名应该加载的关联。命名符号表示已定义的关联。 - 来自Rails API的引用。