Recipe 5.8. Generating RSS Feeds from Active Record Data


Problem

You want your application to provide syndicated data from its model in the form of an Really Simple Syndication (RSS) feed. For example, you have product information in your database. This data changes often; you want to offer RSS as a convenient means for customers to keep abreast of these changes.

Solution

Build support for RSS by having an action that generates RSS XML dynamically using Builder templates. For example, let's say you have the following schema that defines a table of books. Each record includes sales information that changes often.

db/schema.rb:

ActiveRecord::Schema.define() do   create_table "books", :force => true do |t|     t.column "title", :string, :limit => 80     t.column "sales_pitch", :string      t.column "est_release_date", :date   end end

Create an action called rss in an Xml Controller that assembles information from the Book model into an instance variable to be used by the Builder template:

app/controllers/xml_controller.rb:

class XmlController < ApplicationController   def rss     @feed_title = "O'Reilly Books"     @books = Book.find(:all, :order => "est_release_date desc",                               :limit => 2)   end end

In the view associated with the rss action, use Builder XML markup constructs to create RSS XML containing the contents of the @feed_title and @books instance variables.

app/views/xml/rss.rxml:

xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8" xml.rss('version' => '2.0') do   xml.channel do     xml.title @feed_title     xml.link(request.protocol +        request.host_with_port + url_for(:rss => nil))     xml.description(@feed_title)     xml.language "en-us"     xml.ttl "40"     # RFC-822 dateime example: Tue, 10 Jun 2003 04:00:00 GMT     xml.pubDate(Time.now.strftime("%a, %d %b %Y %H:%M:%S %Z"))     @books.each do |b|       xml.item do         xml.title(b.title)         xml.link(request.protocol + request.host_with_port +            url_for(:controller => "posts", :action => "show", :id => b.id))         xml.description(b.sales_pitch)         xml.guid(request.protocol + request.host_with_port +            url_for(:controller => "posts", :action => "show", :id => b.id))       end          end        end end

Discussion

RSS feeds allow users to track frequent updates on a site using an aggregator, such as NetNewsWire or the Sage Firefox extension. The use of RSS feeds and aggregators makes it much easier to keep up with a vast amount of constantly changing information. RSS feeds typically offer a title and a brief description, accompanied by a link to the full document that the item summarizes.

The first line in the rss.rxml template creates the XML declaration that defines the XML version and the character encoding used in the document. Then the root element is created; the root contains all of the remaining elements. Item elements are generated by looping over the objects in @books and creating elements based on attributes of each Book object.

With the Book.find call in the rss action limited to return two objects, the solution's resultant RSS feed returns the following:

<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0">   <channel>     <title>Recent O'Reilly Books</title>     <link>http://orsini.us:3000/xml/rss</link>     <description>Recent O'Reilly Books</description>     <language>en-us</language>     <ttl>40</ttl>     <pubDate>Sun, 30 Apr 2006 17:34:20 PDT</pubDate>     <item>         <title>Revolution in The Valley</title>       <link>http://orsini.us:3000/posts/show/20</link>       <description>Credited as the  co-creator of the Macintosh Computer, Andy Herzfeld offers an insider s account of the events and personalities leading up to the release of this revolutionary machine.</description>       <guid>http://orsini.us:3000/posts/show/20</guid>     </item>      <item>         <title>Excel 2003 Personal Trainer</title>       <link>http://orsini.us:3000/posts/show/17</link>       <description>Beginning with spreadsheet basics, this complete workout  takes you through editing and formatting, working with formulas, charts and graphs, macros, integrating excel with other programs, and a variety of advanced topics.</description>       <guid>http://orsini.us:3000/posts/show/17</guid>     </item>    </channel> </rss>

The relatively verbose call to Time.now.strftime is necessary to create a valid RFC-822 date-time string, as required by the RSS 2.0 specification (Ruby's Time.now method is missing a comma).

See Also

  • W3C FEED Validation Service, http://validator.w3.org/feed

  • RSS 2.0 specification, http://blogs.law.harvard.edu/tech/rss




Rails Cookbook
Rails Cookbook (Cookbooks (OReilly))
ISBN: 0596527314
EAN: 2147483647
Year: 2007
Pages: 250
Authors: Rob Orsini

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net