user3127502 February 2016

Rake task to create a Rails partial from json data

Right now I have a helper:

def blog_posts
  Rails.cache.fetch("blog_posts", :expires_in => 30.minutes) do
    url = URI('http://www.xxxxxxxx.com/blog/?json=get_recent_posts')
    request = Net::HTTP.get(url)
    response = JSON.parse(request)
    response['posts'].take(4)
  end
rescue => e
  logger.error "Error retrieving blog posts!"
  logger.error "#{e.message}\n#{e.backtrace.join("\n")}"
  []
end

And the view I have:

<% blog_posts.each do |blog| %>
  <div class="col col-3">
    <a class="search-page-links" href="<%= blog['url'] %>" target="_blank">
      <img class="post-image" src="<%= blog['thumbnail'] %>">
      <br/><br/>
      <%= blog['title'].html_safe %>
    </a>
  </div>
<% end %>

Which works fine. Except we dont want the data to be pulled when the page loads at all anymore, because we cant always count on the source. The plan is to add a Rake task to the deploy process so that static data can be updated in a rails partial at each deploy, which would be rendered into the view. How could I go about doing this?

Answers


max February 2016

Creating partials just sound like the worst possible solution because you are creating a huge amount of code duplication, and potentially a huge slug (deployed code base). If you have to then save the JSON data to disk and use fragment caching if needed.

Other alternatives would be to use a key/value or JSON based storage instead of storing the data in your codebase (which is almost always a bad idea).

I would sit down with the client or whoever is making up the rules and explain that it would be a pretty big maintenance problem down the line and suggest a solution that is actually tenable.


user3127502 February 2016

What I did

Rake Task:

namespace :blog do

  task :pull do
    tmp = "tmp/blog_posts"

    def fetch_blog_posts
      json = open('http://www.xxxxx.com/blog/?json=get_recent_posts').read
      hash = JSON.parse(json)
      hash['posts'].take(4)
    end

    def download_blog_images
      fetch_blog_posts.each_with_index do |blog, index|
        File.open("tmp/#{index}.jpg", 'wb') do |f|
          f.write open("#{blog['thumbnail']}").read
        end
        puts "Downloaded #{(index.to_i+1).ordinalize} Image" 
      end
    end

    def retrieve_blog_data
      puts 'Retrieving blog data from Wordpress'
      fetch_blog_posts

      File.open("tmp/blog_posts.json", "w+") do |f|
        f.write(JSON.pretty_generate(fetch_blog_posts))
        puts 'Saved json data'
      end
      download_blog_images
    end

    retrieve_blog_data
    puts 'Done retrieving blog posts'
  end

end

Helper:

module BlogHelper

  def blog_posts
    if Rails.env.development?
      json = open('http://xxxxx/blog/?json=get_recent_posts').read
    else
      json = File.read("tmp/blog_posts.json")
    end
    hash = JSON.parse(json)
    hash['posts'].take(4)
  end

end

Controller:

def home
  @blog_posts = blog_posts
end

View:

<% @blog_posts.each_with_index do |blog, index| %>
  # markup for each post...
<% end %>

Post Status

Asked in February 2016
Viewed 1,511 times
Voted 7
Answered 2 times

Search




Leave an answer