--- /dev/null
+# Filters added to this controller apply to all controllers in the application.
+# Likewise, all the methods added will be available for all controllers.
+
+class ApplicationController < ActionController::Base
+ helper :all # include all helpers, all the time
+ protect_from_forgery # See ActionController::RequestForgeryProtection for details
+
+ # Scrub sensitive parameters from your log
+ # filter_parameter_logging :password
+end
--- /dev/null
+class FeedController < ApplicationController
+
+ skip_before_filter :verify_authenticity_token
+
+ def index
+ @feeds = FeedItem.find(:all, :select => 'DISTINCT feed_name')
+ respond_to do |format|
+ format.html
+ format.rss { render :layout => false }
+ end
+ end
+
+ def show
+ @feed_items = FeedItem.find_all_by_feed_name(params[:feed_name])
+ redirect_to index_url if @feed_items == []
+ respond_to do |format|
+ format.html
+ format.rss { render :layout => false }
+ end
+ end
+
+ def update
+ item = FeedItem.find_by_feed_name_and_title(params[:feed_name], params[:title])
+ if item
+ if params[:description] == ''
+ item.destroy
+ else
+ item.update_attribute(:description, params[:description])
+ end
+ else
+ FeedItem.create(:feed_name => params[:feed_name],
+ :title => params[:title],
+ :description => params[:description])
+ end
+ redirect_to feed_url(params[:feed_name])
+ end
+
+end
--- /dev/null
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+end
--- /dev/null
+module FeedHelper
+end
--- /dev/null
+class FeedItem < ActiveRecord::Base
+
+ # require 'cgi' # needed for url decoding
+
+ validates_presence_of :feed_name, :title, :description
+ validate :feed_name_must_be_legal
+
+protected
+
+ def feed_name_must_be_legal
+ if Rack::Utils::escape(feed_name) != feed_name or
+ Rack::Utils::unescape(feed_name) != feed_name or
+ feed_name == 'index' or
+ feed_name == 'show' or
+ feed_name == 'update' or
+ feed_name == 'action'
+ errors.add(:feed_name, 'is an invalid feed name')
+ end
+ end
+
+end
--- /dev/null
+<h1>Feeds available</h1>
+
+<% form_tag :action => 'update' do %>
+ <p>Set feed <%= text_field_tag :feed_name, '', :size => 20 %>
+ to include <%= text_field_tag :title, '', :size => 30 %>
+ containing <%= text_field_tag :description, '', :size => 50 %>
+ <%= submit_tag 'Update' %></p>
+<% end %>
+
+<ul>
+<% for feed in @feeds %>
+ <li><%= link_to(h(feed.feed_name), (feed_url(:feed_name => feed.feed_name))) %></li>
+<% end %>
+</ul>
\ No newline at end of file
--- /dev/null
+# index.rss.builder
+xml.instruct! :xml, :version => "1.0"
+xml.rss :version => "2.0" do
+ xml.channel do
+ xml.title "Feedcatcher"
+ xml.description "Feeds available"
+ xml.link index_url(:rss)
+
+ for feed in @feeds
+ xml.item do
+ xml.title feed.feed_name
+ xml.link feed_url(feed.feed_name, :rss)
+ xml.guid feed_url(feed.feed_name, :rss)
+ end
+ end
+ end
+end
--- /dev/null
+<h1>Contents of feed <%= h params[:feed_name] %></h1>
+<p><%= link_to("List of all feeds", index_url) %></p>
+
+<% form_tag :action => 'update' do %>
+ <p>Set feed <%= text_field_tag :feed_name, h(params[:feed_name]), :size => 20 %>
+ to include <%= text_field_tag :title, '', :size => 30 %>
+ containing <%= text_field_tag :description, '', :size => 50 %>
+ <%= submit_tag 'Update' %></p>
+<% end %>
+
+
+<dl>
+ <% for item in @feed_items %>
+ <dt><%= h item.title %></dt>
+ <dd><em><%= h item.description %></em></dd>
+ <% end %>
+</dl>
--- /dev/null
+# index.rss.builder
+xml.instruct! :xml, :version => "1.0"
+xml.rss :version => "2.0" do
+ xml.channel do
+ xml.title @feed_items[0].feed_name
+ xml.link feed_url(@feed_items[0].feed_name, :rss)
+
+ for item in @feed_items
+ xml.item do
+ xml.title item.title
+ xml.description item.description
+ xml.guid item.id, :isPermaLink => 'false'
+ end
+ end
+ end
+end
--- /dev/null
+<h1>Feed#update</h1>
+<p>Find me in app/views/feed/update.html.erb</p>
--- /dev/null
+<html>
+ <head>
+ <title>Form: <%= controller.action_name %></title>
+ </head>
+ <body>
+ <%= yield :layout %>
+ </body>
+</html>