如何在复杂的嵌套关联中使用带范围的预先加载?

时间:2013-08-29 10:53:07

标签: ruby-on-rails ruby-on-rails-3 eager-loading

我有4个模型,如下面的

  • 用户(有1个个人资料,许多社区和许多代码)
  • 个人资料(属于用户)
  • 社区(包含许多代码,属于用户)
  • 代码(属于社区和用户)

现在我正在尝试显示属于特定社区的code的10条记录。

code包含外部表格的信息,例如

  • username(in user table)
  • comment(in profile table)
  • point(in profile table)

现在,它发出了许多sql查询,因为我没有使用急切的加载 在这种情况下,我如何自定义代码以进行这种急切加载以加快加载速度?

控制器/ communities_controller.rb

#CanCan load_and_authorize_resouce
load_and_authorize_resource :find_by => :community_name,

模型/ community.rb

belongs_to :user
has_many :codes

模型/ code.rb

belongs_to :user, counter_cache: true
belongs_to :community, counter_cache: true

scope :recent, lambda { |n = 10| includes(:user).where('users.deleted_at' => nil).order("users.last_active_at DESC").limit(n) }

模型/ user.rb

has_one :profile
has_many :communities
has_many :codes

模型/ profile.rb

belongs_to :user

视图/ communityes / show.html.erb

<% @community.codes.recent.each do |code| %>
    <%= render 'codes/code', {:code => code, :icon_photo => code.user.profile.user_avatar} %>
<% end %>

视图/ communityes / _code.html.erb

<tr>
    Username: <%= code.user.username %> <br />
    Code: <%= code.data %> <br />
    Comment: <%= code.user.profile.comment %> <br />
    Point: <%= code.user.profile.point.to_s %>
</tr>

1 个答案:

答案 0 :(得分:1)

不应该特别复杂,只需要.includes您想要加载的所有位......

@community.codes.recent.includes(user: :profile)

此外,Community的代码是否总是等于User的所有代码?如果是这样,您应该在has_many :codes, through: :users上使用Community关联。