Generating RSS in Rails
Generating RSS in Rails 2 is pretty easy.
In the simplest case, all that is required is an extra view file to create the RSS output.
Consider a simple (RESTful) blog example:
route.rb:
...
map.home '', :controller => 'posts', :action => 'index'
map.resources :posts
...
posts_controller.rb:
def index
@posts = Post.find(:all)
end
When I generated the posts controller, Rails created an ‘index.html.erb’ file for the index action. It’s an ugly file name, but it helps Rails figure out what to do: ‘index’ is the action, ‘html’ and ‘erb’ are the format and builder to use. To generate RSS we want to use the XML Builder, so the file name to use is ‘index.rss.builder’. And the file contents should look something like this:
xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
xml.channel do
xml.title "My Blog"
xml.description "My Fantastic Blog"
xml.link posts_url
for post in @posts
xml.item do
xml.title post.title
xml.description post.content
xml.pubDate post.created_at.to_s(:rfc822)
xml.link post_url(post)
end
end
end
end
Now that is really easy, but I’ve experienced two issues with this.
The first issue is with layouts. If the controller uses a layout for all actions (using layout => "mylayout") it will cause Rails to look for a layout file named ‘layouts/posts.rss.erb’. This can be bypassed by excluding the layout for the rss format, like so:
def index
@posts = Post.find(:all)
respond_to do |format|
format.html
format.rss { render :layout => false }
end
end
The other issue I experienced was with the will_paginate plug-in where my index method looks like this:
def index
@posts = Post.paginate(:per_page => 10, :page => params[:page])
end
The problem is that only 10 posts will show up in the RSS feed, which is not what I want.
There are at least two good ways I came up with to deal with this issue. The my preferred way is create a new feed method that is excluded from the layout and returns all posts.
def feed
@posts = Post.find(:all)
end
with a new route:
map.connect 'posts/feed.:format', :controller => 'posts', :action => 'feed'
The second way examines the request format and grabs the posts via paginate for HTML and find for RSS
def index
if request.format.html?
@posts = Post.paginate(:per_page => 10, :page => params[:page])
else
@posts = Post.find(:all)
end
respond_to do |format|
format.html
format.rss { render :layout => fals }
end
end
I like the first way better. Seems a little cleaner. I like small methods.
Popularity: 100%
Comment by Shagy
Have you tested this? It doesn’t work for me. What link would you put in the RSS reader?
Added May 22, 2008 @ 6:42 pm
Comment by todd
You would use hostname/controller_name/feed.rss but more likely you’d use < %= auto_discovery_link_tag(:rss, {:controller => “controller_name”, :action => “feed”, :format => “rss”}) %> in the <head> of your page.
Added May 22, 2008 @ 6:51 pm
Comment by Shagy
I’ve tried everything and can’t get rss feeds to generate from my rails 2.0.2 app.
Do you HAVE to use restful routes? I’ve tried with and without.
just can’t get it to work and been trying for 2 days.
Added May 22, 2008 @ 7:02 pm
Comment by James
Nice stuff. This works well for me, but I have yet to figure out how to add an image to my feed, probably because I am a noob. Would you use an enclosure or the images array? Almost all of my rss items will have at least one image. It sure would be nice if someone would just write a to_rss method that works just like to_xml.
Added June 19, 2008 @ 4:13 am
Comment by todd
James, I have not tried adding images, but if you do I will post the solution.
Added June 19, 2008 @ 4:42 pm
Comment by todd
Shagy, you do not have to use restful routes, that’s just my example. What’s your issue?
Added June 19, 2008 @ 4:42 pm
Comment by leethal
http://pastie.org/258522 imo!
Added August 23, 2008 @ 10:19 am
Pingback by trivialview » Immer up to date
[…] Generating RSS in Rails […]
Added October 4, 2008 @ 12:36 pm
Comment by niccon
thanks for this post, this definitely helped with my issues for will_paginate and rss!
Added November 14, 2008 @ 10:31 pm
Comment by Tania
Thanks for this post! you explained it perfectly!
Added January 11, 2011 @ 2:56 pm