来自Rails模型的实例变量:未定义的方法`any?'

时间:2015-03-28 09:51:20

标签: ruby-on-rails

尝试显示一些联盟产品,同时尽可能保持控制器的瘦。但有人知道为什么这不起作用吗?

undefined method `any?' for nil:NilClass

应用/模型/ shopsense.rb

require "rest_client"

module Shopsense
  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"
    )

    # !!! ATTENTION !!!
    #
    # It works if I put the below in `shopsense` in the controller instead
    #

    @products = JSON.parse(response)["products"].map do |product|
      product = OpenStruct.new(product)
      product
    end
  end
end

应用/控制器/ main_controller.rb

class MainController < ApplicationController
  before_action :shopsense

  def index
  end

  def shopsense
    Shopsense.fetch
  end
end

应用/视图/主/ index.html.erb

<% if @products.any? %>
  <% @products.each do |product| %>
    <div class="product">
      <%= link_to product.name %>
    </div>
  <% end %>
<% end %>

4 个答案:

答案 0 :(得分:1)

实例变量不属于模型。所以你不能在那里使用@products。把它放回控制器,你很好。

答案 1 :(得分:1)

您的index.html.erb正在请求实例变量@products,该变量在您的控制器的索引操作中无法使用。

将实例变量放在索引操作中:

def index
  @products = Shopsense.fetch
end

答案 2 :(得分:1)

正确 - 视图中提供了控制器中声明的rails中的实例变量。在您的情况下,您在模块内声明实例变量,而不是控制器。

试试这个:

def index @products = shopsense end

在这种情况下,您的控制器会将@products实例变量传递给视图

答案 3 :(得分:1)

因为@products应该是MainController的成员才能在视图中可见。

这应该有效:

class MainController < ApplicationController
  before_action :shopsense

  ...

  def shopsense
    @products = Shopsense.fetch
  end
end

另一个选择是将Shopsense模块包含在MainController中:

module Shopsense
  def fetch
      ...
  end
end

class MainController < ApplicationController
  include Shopsense

  before_action :fetch

  ...
end