51 votes

Générer un flux RSS dans Rails 3

Je suis à la recherche d'une meilleure pratique/un modèle standard pour générer des flux dans Rails 3. Est-ce que http://railscasts.com/episodes/87-generating-rss-feeds encore valable ?

113voto

tomeduarte Points 2013

Tout d'abord, de nos jours Je recommande d'utiliser un flux ATOM au lieu d'un flux RSS. .

La spécification du flux ATOM offre plus de valeur que celle du flux RSS en ce qui concerne l'internationalisation, les types de contenu et d'autres éléments. et tous les lecteurs de flux modernes le prennent en charge.

Vous trouverez plus d'informations sur ATOM et RSS à l'adresse suivante :


Passons au codage :

Cet exemple suppose :

  • un modèle appelé NewsItem avec les attributs suivants :
    • title
    • content
    • author_name
  • un contrôleur pour ce modèle ( news_items_controller.rb ), à laquelle vous ajouterez le feed action

Nous utiliserons un modèle de construction pour ce faire et l'application Ruby on Rails aide atom_feed qui est d'une grande utilité.

1. Ajoutez l'action au contrôleur

Aller à app/controllers/news_items_controller.rb et ajoutez :

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. Configurez votre modèle de construction

Maintenant, ajoutons le modèle pour construire le flux.

Aller à app/views/news_items/feed.atom.builder et ajoutez :

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. Connectez-le avec une route

Rendons les flux disponibles à http://domain.com/feed

Ceci appellera l'action avec le format ATOM par défaut et redirigera /feed.rss à /feed.atom .

Aller à config/routes.rb et ajoutez :

resources :news_items
match '/feed' => 'news_items#feed',
      :as => :feed,
      :defaults => { :format => 'atom' }

4. Ajouter le lien vers les flux ATOM et RSS sur la mise en page

Enfin, il ne reste plus qu'à ajouter le flux à la mise en page.

Aller à app/views/layouts/application.html.erb et ajoutez ceci à votre <head></head> section :

<%= auto_discovery_link_tag :atom, "/feed" %>
<%= auto_discovery_link_tag :rss, "/feed.rss" %>

Il peut y avoir une ou deux fautes de frappe, alors faites-moi savoir si cela fonctionne pour vous.

10voto

holden Points 5603

J'ai fait quelque chose de similaire mais sans créer une nouvelle action.

index.atom.builder

atom_feed :language => 'en-US' do |feed|
  feed.title "Articles"
  feed.updated Time.now

  @articles.each do |item|
    next if item.published_at.blank?

    feed.entry( item ) do |entry|
      entry.url article_url(item)
      entry.title item.title
      entry.content item.content, :type => 'html'

      # the strftime is needed to work with Google Reader.
      entry.updated(item.published_at.strftime("%Y-%m-%dT%H:%M:%SZ")) 
      entry.author item.user.handle
    end
  end
end

Vous n'avez pas besoin de faire quoi que ce soit de spécial dans le contrôleur, sauf si vous avez un code spécial comme moi. Par exemple, j'utilise la gemme will_paginate et pour le flux atomique je ne veux pas qu'il pagine donc j'ai fait ceci pour éviter cela.

contrôleur

  def index
    if current_user && current_user.admin?
      @articles = Article.paginate :page => params[:page], :order => 'created_at DESC'
    else
      respond_to do |format|
        format.html { @articles = Article.published.paginate :page => params[:page], :order => 'published_at DESC' }
        format.atom { @articles = Article.published }
      end
    end
  end

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X