完成项目后,使用路线从视图中进行检查

时间:2015-06-06 22:46:38

标签: ruby-on-rails

在完成REST Client时,使用路由从JS检查,在后台(DelayedJob)从此外部API获取项目。路由部分工作正常,但如何从视图中重用相同的@items_status,以便Ajax实际上可以加载项并在完成后插入它们?

您可以即时投放的实时应用http://runnable.com/VXIdQ6KuRrYPdhKs/rest-client-ajaxhttps://gist.github.com/dt1973/b57d84bf39a75ea47e9b

index.html.erb

<!-- THIS ALWAYS RETURNS FALSE EVEN WHEN TRUE -->

<% if @items_status %>
  <div class="products">
    <% @products.each do |product| %>
      <div class="product">
        <%= link_to product.name, product.url %>
      </div>
    <% end %>
  </div>
<% else %>
  <div class="products processing">
    <p>Currently fetching.. come back later</p>

    <!-- Fetch via Ajax later -->

  </div>
<% end %>

check_items_loaded.js.erb

<!-- This seems to return true properly though -->

alert("<%= @items_status %>"); 

的routes.rb

get '/check_items_loaded', to: 'main#check_items_loaded', as: :check_items_loaded

main_controller.rb

class MainController < ApplicationController
  def index
    # Delay fetching
    @products = Affiliate.delay.fetch
  end

  def check_items_loaded
    @items_status = Affiliate.where(url: params[:url]).exists?
    respond_to do |wants|
      wants.js
    end
  end
end

affiliate.rb

require "rest_client"

class Affiliate < ActiveRecord::Base
  def self.fetch
    response = RestClient::Request.execute(
      :method => :get,
      :url => "http://api.shopstyle.com/api/v2/products?pid=uid7849-6112293-28&fts=women&offset=0&limit=10"
    )

    @products = JSON.parse(response)["products"].map do |product|
      product = OpenStruct.new(product)
      affiliate = Affiliate.find_or_create_by(:name => product.name, :url => product.url)
      affiliate.save
    end
  end
end

1 个答案:

答案 0 :(得分:2)

您必须重复使用用于检查项目是否被提取的路由,而不是视图中的实例@items_status

在您的Ajax部分中,您基本上必须继续查询路由以检查是否已完成提取,并且当它完成时,您必须向另一个路由发出请求以将获取的项目返回到页面。

所以制作另一条路线,如get_items_fetched,我认为最好的回应是包含这些项目的json数据。例如:

def get_fetched_items
  respond_to do |format|
    format.json do 
      render json: @products
    end
  end
end

您应该在/get_items_fetched.json获取json数据。

更新1:

获取商品状态和商品的正确方法如下:

AJAX部分:

  • 首先将setTimeout更改为setInterval,因此它会自动保持对item_status的轮询。但是如果您有自己的理由使用setTimeout,那么您可以忽略它。

     poll: function() {
       console.log('Ran `poll`');
       // Change here, setTimeout to setInterval.
       window.pollInterval = setInterval(this.request, 3000);
     },
    
  • 其次检查为轮询请求返回的item_status,不要在错误部分重试。

    request: function() {
    
      console.log('Ran `request`');
      $.ajax({
        url: "/check_items_loaded",
        type: "GET",
    
        // Change here ! Added the checking of the item status returned.
        // Why ? Previsouly it wasn't checking at all. So if the request was
        // successful, it meant the items_status was also true.
        success: function(data){
          // Note if the data has the json MIME type, it'll be automatically
          // converted to a JavaScript object.
          if(data.item_status == true) {
            console.log('Items now ready');
            $.restClient.addItems();
    
            // Now you don't have to poll anymore, so clear interval.
            clearInterval(window.pollInterval);
          }
          else 
            console.log('Fetching going on ...');
        },
        error: function() {
          console.log('Request was not completed successfully.');
        }
      });
    },
    
  • 接下来,解析您在addItems的响应中获得的HTML。默认情况下,如果响应是HTML,则会将其作为纯文本提供。

    addItems: function() {
      console.log('Ran `addItems`');
    
      var dataUrl = '/';
    
      $.get(dataUrl, function(data) {
        // Parsing it first.
        var html = $.parseHTML(data);
        $(html).find('.product').appendTo($('body'));
        console.log(html);
      });
    
      console.log('New items were added');
    }
    
  • 现在在后端,/check_items_done路线部分:

     def check_items_loaded
      @items_status = Affiliate.where(url: params[:url]).exists?
      render json: {item_status: @item_status}
     end