intertwingly

It’s just data

Rails’ AtomFeedHelper just got better


Rails has an AtomFeedHelper that I just helped improve.

If you look at a feed, it contains things like authors, ids, links, dates, and text.  Rails already knows about ids, links, and dates, so it can provide reasonable defaults for these that you can override if you need to, but otherwise generally don’t have to worry about.  That leaves only authors and text for a minimal but complete feed.  Author information generally either comes naturally from the data, or is something that you set once at the feed level.  That leaves text.

Unless you are writing blog software, an ActiveRecord doesn’t have typically have “content”.  This means that you have to synthesize a summary from the data.  Of course, one can do this via string concatenation and interpolation, but this gets messy quick if you are talking about loops.  Builder provides a much cleaner way.

atom_feed do |feed|
  feed.title "Who bought #{@product.title}"
  feed.updated @orders.first.created_at

  for order in @orders
    feed.entry(order) do |entry|
      entry.title "Order #{order.id}"
      entry.summary :type => 'xhtml' do |xhtml|
        xhtml.p "Shipped to #{order.address}"

        xhtml.table do
          xhtml.tr do
            xhtml.th 'Product'
            xhtml.th 'Quantity'
            xhtml.th 'Total Price'
          end
          for item in order.line_items
            xhtml.tr do
              xhtml.td item.product.title
              xhtml.td item.quantity
              xhtml.td number_to_currency item.total_price
            end
          end
          xhtml.tr do
            xhtml.th 'total', :colspan => 2
            xhtml.th number_to_currency order.line_items.map(&:total_price).sum
          end
        end

        xhtml.p "Paid by #{order.pay_type}"
      end
      entry.author do |author|
        entry.name order.name
        entry.email order.email
      end
    end
  end
end

Expect to see this example in the next beta of Agile Web Development With Rails, Edition 3.