简体   繁体   中英

How do I cache a parsed RSS feed in Rails 4.0?

I'm working on a site that will be showing a list of recent blog posts on the home page.

What would be the best approach for how to cache and update the list of blog posts? I need to also make sure it fails gracefully in the event the feed url is down or cannot be parsed for whatever reason.

I'm also looking for opinions on how and where to structure this code since I am new to Rails and its conventions (eg: should I create a helper? should this be in a module? etc).

Here's the code I have:

require 'simple-rss'
require 'open-uri'

class PagesController < ApplicationController
  def home

    rss = SimpleRSS.parse(open("#{Settings.my_site.blog_feed}"))
    @blog_posts = []
    rss.channel.items[0..4].each_with_index do |item, index|
      @blog_posts[index] = {
        title:    item.title,
        link:     item.link,
        pub_date: item.pubDate
      }
    end

    render layout: 'home'
  end

The view:

   #blog-updates
    %h2
      %span.sprite>
      Latest Blog Posts
    %ul
      - @blog_posts.each do |blog|
        %li
          =link_to truncate("#{blog[:title]}".html_safe, length: 75, seperator: ' ', omission: "&hellip;"), "#{blog[:link]}"

Firstly, some minor points:

  1. Your controller should probably not be named PagesControllerController unless it's actually a controller of a controller.
  2. I'd write @blog_posts.each do |post| instead of @blog_posts.each do |blog| . You are iterating over posts, not blogs.

What you are doing (downloading and parsing data from an external source) does not really belong in a controller. The controller is for connecting the model with the view, not to implement your logic. It does not belong in a helper either, as those are for creating view helpers. The best place to put it would be in a 'fake' model:

#!app/models/blog_post.rb
class BlogPost
    attr_accessor :title, :body, :url, :etc

    def self.all
      // fetch and parse the posts into an array of BlogPosts
    end
end

This will work, but it's a very bad idea . Each time that page is loaded you also request an external feed. This will make your page load slower, and if your app becomes really popular it will be very taxing on your server. As you mentioned you are also missing out on stability - if the feed goes down for a few hours your feed will go down as well.

What you really want to do is to parse that feed every hour(or day, minute, 30 seconds, whatever you need) and save the posts in your database. To do this, create a rails runner and use whenever or pure cronjobs to schedule it. That makes showing the posts as easy as selecting them from the database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM