Search code examples
ruby-on-railsruby-on-rails-3ruby-on-rails-3.1

DRYing up my view


I have a code snippet which make an API call, which is currently used in 3 different view files (all belonging to different controllers).

My code:

<%  url_raw = URI.parse("url-tem_id=#{rec.id}") %>
<%  url = Net::HTTP.get_response(url_raw).body %>
<%  if url.empty? %>
    <%  @title          = "Product Unavailable via API" %>
    <%  @url            = "url" %>
    <%  @cover_img      = "180X180.jpg" %>
    <%  @price          = "Product Unavailable via API" %>
<% else %>
<%  begin %>
<%  @response1  = JSON.parse(url) %>
<%  @title          = @response1["ProductName"]%>
<%  @url            = "{@response1["ProductUrl"]}"%>
<%  @cover_img      = @response1["ImagePath"].gsub("75X75.gif", "500X500.jpg")%>
<%  @price          = @response1["currentItemPrice"]%>
<%  rescue %>
<%  end %>
<%  end %>

Im really confused about if this should be moved to a partial, helper, or application controller? Also, once this is moved, how do I call it in my view and pass in the rec.id variable?


Solution

  • I think this should all be model logic... it all seems to relate to setting up attributes of a model.

    I assume the "rec" is a model of some description, in which case:

    # all psuedo-code... written off the top of my head and cut/pasting your example... ie: untested!
    class Rec < AR::Base
      attr_reader :title, :url, :cover_img, :price
    
      def call_api!
        url_raw = URI.parse("url-tem_id=#{self.id}")
        url = Net::HTTP.get_response(url_raw).body
        if url.empty?
          @title          = "Product Unavailable via API"
          @url            = "url" 
          @cover_img      = "180X180.jpg" 
          @price          = "Product Unavailable via API" 
        else 
          begin 
            response = JSON.parse(url)
            @title          = response["ProductName"]
            @url            = response["ProductUrl"]
            @cover_img      = response["ImagePath"].gsub("75X75.gif", "500X500.jpg")
            @price          = response["currentItemPrice"]
          rescue 
        end 
    
      end
    end
    

    Then in your controller you can call "rec.call_uri!", and the views can access "rec.price", etc (personally, I'd do it slightly differently, but this shows a first-stage refactor of the code you have).

    If you need it in multiple models, extract it to a module and include it.