I'm looking for a best practice/standard pattern for generating feeds in Rails 3. Is http://railscasts.com/episodes/87-generating-rss-feeds still valid?
First of all, nowadays I recommend using an ATOM feed instead of RSS.
The specification of ATOM feed offers more value than the RSS one with internationalization, content types and other things and every modern feed reader supports it.
More info about ATOM vs RSS can be found at:
On to the coding:
This example assumes:
NewsItem
with the following attributes:
title
content
author_name
news_items_controller.rb
), to which you'll add the feed
actionWe'll use a builder template for this and the Ruby on Rails atom_feed helper which is of great use.
1. Add the action to the controller
Go to app/controllers/news_items_controller.rb
and add:
def feed
# this will be the name of the feed displayed on the feed reader
@title = "FEED title"
# the news items
@news_items = NewsItem.order("updated_at desc")
# this will be our Feed's update timestamp
@updated = @news_items.first.updated_at unless @news_items.empty?
respond_to do |format|
format.atom { render :layout => false }
# we want the RSS feed to redirect permanently to the ATOM feed
format.rss { redirect_to feed_path(:format => :atom), :status => :moved_permanently }
end
end
2. Setup your builder template
Now let's add the template to build the feed.
Go to app/views/news_items/feed.atom.builder
and add:
atom_feed :language => 'en-US' do |feed|
feed.title @title
feed.updated @updated
@news_items.each do |item|
next if item.updated_at.blank?
feed.entry( item ) do |entry|
entry.url news_item_url(item)
entry.title item.title
entry.content item.content, :type => 'html'
# the strftime is needed to work with Google Reader.
entry.updated(item.updated_at.strftime("%Y-%m-%dT%H:%M:%SZ"))
entry.author do |author|
author.name entry.author_name
end
end
end
end
3. Wire it up with a route
Let's make the feeds available at http://domain.com/feed
This will call the action with the ATOM format by default and redirect /feed.rss
to /feed.atom
.
Go to config/routes.rb
and add:
resources :news_items
match '/feed' => 'news_items#feed',
:as => :feed,
:defaults => { :format => 'atom' }
4. Add the link to ATOM and RSS feeds on the layout
Finally, all that is left is to add the feed to the layout.
Go to app/views/layouts/application.html.erb
and add this your <head></head>
section:
<%= auto_discovery_link_tag :atom, "/feed" %>
<%= auto_discovery_link_tag :rss, "/feed.rss" %>
There may be a typo or two in that, so let me know if this works for you.