【Rails学习笔记】用户关注功能(四)

这篇博客主要介绍了在Ruby on Rails中如何改进动态列表,以展示用户及其关注者的微博。通过优化代码,避免将所有关注者ID加载到内存中,而是利用SQL子查询在数据库层面进行操作,提高了效率。同时,还提及了在主页添加分页功能的支持,以完善用户体验。
摘要由CSDN通过智能技术生成

最后一节是用来实现动态列表。

在上一章我们已经初步实现了动态列表,但那时候我们还没有实现用户之间的关注功能,显示的只是自己的微博,这里我们要改进一下,使其实现自己和所关注用户的微博。


举个例子:id 为 1 的用户关注了 id 为 2,7,8,10 的用户后得到的动态列表


feed稍作改进:

class User < ActiveRecord::Base
  .
  .
  .
  def feed
    Micropost.from_users_followed_by(self)
  end
  .
  .
  .
end

from_users_followed_by 方法的初步定义:

class Micropost < ActiveRecord::Base
  .
  .
  .
  def self.from_users_followed_by(user)
    followed_user_ids = user.followed_user_ids
    where("user_id IN (?) OR user_id = ?", followed_user_ids, user)
  end
end

在某些程序中,这样的初步实现已经能满足大部分需求了。不过这不是我们最终要使用的实现方式,当动态列表中的微博数量很多时性能就会下降,这种情况可能会发生在用户关注了 5000 个用户后。本小节,我们会重新实现动态列表,在关注用户数量很多时,性能表现也会很好。


上面所用代码的问题在于followed_user_ids = user.followed_user_ids 这行代码,它会把所有被关注用户的 id 取出存入内存,然后再创建一个元素数量和被关注用户数量相同的数组。既然它的目的只是为了检查集合是否包含了指定的元素,那么就一定存在一种更高效的方法,其实 SQL 真的提供了针对这种问题的优化措施:使用子查询把查询被关注用户 id 的操作放入数据库层进行。

class Micropost < ActiveRecord::Base
  belongs_to :user
  default_scope -> { order('created_at DESC') }
  validates :content, presence: true, length: { maximum: 140 }
  validates :user_id, presence: true

  # Returns microposts from the users being followed by the given user.
  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
          user_id: user.id)
  end
end

这段代码结合了 Rails、Ruby 和 SQL 的优势,达到了目的,而且做的很好。当然,子查询也不是万能的。对于更大型的网站而言,可能要使用“后台作业(background job)”异步生成动态列表。


最后我们要在home中加入对分页功能的支持

class StaticPagesController < ApplicationController

  def home
    if signed_in?
      @micropost  = current_user.microposts.build
      @feed_items = current_user.feed.paginate(page: params[:page])
    end
  end
  .
  .
  .
end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值