Rake 任务从 json 数据创建 Rails 部分

Rake task to create a Rails partial from json data

现在我有一个帮手:

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

我的观点是:

<% 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 %>

效果很好。除了我们根本不希望在页面加载时提取数据,因为我们不能总是依赖源。计划是在部署过程中添加一个 Rake 任务,以便在每次部署时可以在 rails 局部更新静态数据,这些数据将呈现到视图中。我该怎么做呢?

创建部分听起来像是最糟糕的解决方案,因为您正在创建大量的代码重复,并且可能会产生巨大的 slug(已部署的代码库)。如果您必须将 JSON 数据保存到磁盘并在需要时使用片段缓存。

其他替代方案是使用基于 key/value 或 JSON 的存储,而不是将数据存储在您的代码库中(这几乎总是一个坏主意)。

我会与客户或制定规则的人坐下来解释这将是一个相当大的维护问题,并提出一个实际可行的解决方案。

我做了什么

耙任务:

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

助手:

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

控制器:

def home
  @blog_posts = blog_posts
end

查看:

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