rubyruby-on-rails-3rubygemsfeedzirra

Should I be using Feedzirra in the model?


I'm playing about with the Ruby Feedzirra gem and have managed to acheive what I set out to do by using it in the controller.

Though everything I've seen has mentioned using it in the model. I was just wondering if this is ok to do in the controller, if not, how might I go about achieving the same in the model?

I want to submit a Feed URL and use that to update my model with the rest of the information about the feed.

Feeds_controller.rb

def create
  @feed = Feed.new(params[:feed])

  feed = Feedzirra::Feed.fetch_and_parse(@feed.feed_url)
  @feed.title         = feed.title
  @feed.url           = feed.url
  @feed.last_modified = feed.last_modified

  respond_to do |format|
    if @feed.save
      format.html { redirect_to @feed, notice: 'Feed was successfully created.' }
      format.json { render json: @feed, status: :created, location: @feed }
    else
      format.html { render action: "new" }
      format.json { render json: @feed.errors, status: :unprocessable_entity }
    end
  end
end

feed.rb

class Feed < ActiveRecord::Base
  attr_accessible :feed_url, :last_modified, :title, :url
end

Solution

  • I'd make an instance method on the Model and use that in the controller so

    class Feed < ActiveRecord::Base
       def fetch!
         feed = Feedzirra::Feed.fetch_and_parse(feed_url) # probably want some eror handling here
         title = feed.title
         url = feed.url
         last_modified = feed.last_modified
         self #or nil if you like
       end
    end
    

    then your controller thins down to

    def create
      @feed = Feed.new(params[:feed])
      @feed.fetch!
    
      respond_to do |format|
        if @feed.save
          format.html { redirect_to @feed, notice: 'Feed was successfully created.' }
          format.json { render json: @feed, status: :created, location: @feed }
        else
          format.html { render action: "new" }
          format.json { render json: @feed.errors, status: :unprocessable_entity }
        end
      end
    end
    

    The cool thing here is that if this gets too slow you can use something like Resque to run this in the background and just return a "your request is being processed" message to the user, then alert them asynchronously when the the request is done (might not work so well for the json request)