2016-04-19 1 views
0

J'écris une API JSON Rails 5.Comment mettre en cache les N premiers posts classés par note?

J'ai une action qui retourne haut N messages de blog basé sur note moyenne. Afin de réduire le temps de réponse, j'ai dénormalisé ma base de données de telle sorte que posts ait une colonne average_rating.

Je suis aussi cache chaque requête comme ceci:

# posts_controller.rb 
def top 
    quantity = params[:quantity] 

    if quantity.to_i > 0 
    render json: { 
     posts: cached_top_posts(quantity) 
    }, status: :ok 
    else 
    render json: '', status: :unprocessable_entity 
    end 
end 

def cached_top_posts(quantity) 
    Rails.cache.fetch(['top', quantity], expires_in: 1.hour) do 
    Post.limit(quantity).as_json(only: [:title, :content, :average_rating]) 
    end 
end 

(par ordre average_rating est dans le modèle lui-même)

Je suis conscient que cela est loin d'être optimale.

Bien qu'il améliore considérablement le temps de réponse lors de la demande de la même quantité de messages, il serait beaucoup mieux si, déjà mises en cache top 1000 messages, il ne sera pas cache 100 messages, mais obtiendraient premier 100 messages sur en cache 1000.

Quel est un bon moyen d'y parvenir?

Répondre

0

Eh bien, après une bonne nuit de sommeil, une simple conclusion m'est venue à l'esprit.

Ici, il est:

# posts_controller.rb 
def cached_top_posts(quantity) 
    data = Rails.cache.read('top_posts') 
    if data.nil? || data[:quantity] < quantity 
    data = { 
     :quantity => quantity, 
     :posts => Post.limit(quantity).as_json(only: [:title, :content, :average_rating]) 
    } 
    Rails.cache.write('top_posts', data, expires_in: 1.hour) 
    end 
    data[:posts][0...quantity] 
end