Yêu cầu thg 11 16, 2020 5:54 SA 91 0 1
  • 91 0 1
0

Cache one model trên Ruby on Rails?

Chia sẻ
  • 91 0 1

Chào mọi người

Mình có nhiều model: User, Game, Reward, Histories

Giờ mình muốn cache các SQL query cho mỗi model User (chỉ select query) thì mình config như thế nào vậy?

Mình có thử tìm trên Google mà ko có kết quả

Xin cảm ơn!

1 CÂU TRẢ LỜI


Đã trả lời thg 11 16, 2020 7:04 SA
Đã được chấp nhận
0

Theo mình biết thì Rails mặc định không có kiểu cache chính xác như bạn nói. Tuy vậy Rails có low-level caching mà bạn có thể dùng để cache từng query mà bạn muốn trong khoảng thời gian bạn đặt.

Ví dụ:

class User < ApplicationRecord
  def User.all_cached
    Rails.cache.fetch('users/all', expires_in: 1.day) do
      User.all
    end
  end
end

Sau đó bất cứ chỗ nào bạn cần sử dụng User.all, bạn thay bằng gọi đến User.all_cached. Ngoài ra bất cứ khi nào có thay đổi gì ở bảng users, ví dụ như có người dùng mới đăng ký, người dùng sửa thông tin hay đổi password,... bạn cần phải tự tay invalidate cache ở trên với Rails.cache.delete để dữ liệu được đồng nhất.

Chia sẻ
Avatar daicarun @daicarun
thg 11 18, 2020 6:54 SA

Cảm ơn bạn, mình tự mò được rồi, share lại cho mọi người tham khảo 😄

model: user.rb

def self.find(id)
    user = Rd.user_get(id)
    if !user
      puts "OVERRIDING no user #{id}"
      user = super
      Rd.user_set(id, user, {:ex => 3600})
    end

    return user
  end

services/rd.rb

class Rd
  def self.user_get(id)
    begin
      user = $rd.get("user_info_#{id}")
      puts "user redis #{id}"
      return User.new(JSON.parse(user))
    rescue
      return nil
    end
  end


  def self.user_set(id, user, options={})
    $rd.set("user_info_#{id}", user.to_json, options)
  end
end

$rd là redis client connection chỗ application.rb

$rd = Redis.new(
        :url => "redis://#{ENV['REDIS_CONNECT']}/0",
        :connect_timeout => 0.2,
        :read_timeout    => 1.0,
        :write_timeout   => 0.5
    )
Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí