Reputation: 359
Trying to display some affiliate products while keeping my controllers as skinny as possible. But does anybody know why this isn't working?
undefined method `any?' for nil:NilClass
app/models/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
app/controllers/main_controller.rb
class MainController < ApplicationController
before_action :shopsense
def index
end
def shopsense
Shopsense.fetch
end
end
app/views/main/index.html.erb
<% if @products.any? %>
<% @products.each do |product| %>
<div class="product">
<%= link_to product.name %>
</div>
<% end %>
<% end %>
Upvotes: 0
Views: 195
Reputation: 719
Because @products should be a member of MainController to be visible inside the view.
This should work:
class MainController < ApplicationController
before_action :shopsense
...
def shopsense
@products = Shopsense.fetch
end
end
Another option is to include the Shopsense module into MainController:
module Shopsense
def fetch
...
end
end
class MainController < ApplicationController
include Shopsense
before_action :fetch
...
end
Upvotes: 1
Reputation: 1618
Correct - instance variables in rails declared in the controller are available in the view. In your case, you are declaring the instance variable inside a module, and not the controller.
Try this:
def index
@products = shopsense
end
In this case, your controller will pass on the @products
instance variable to the view
Upvotes: 1
Reputation: 1771
Your index.html.erb is requesting an instance variable @products, which isn't available through in the index action of your controller.
Put the instance variable in your index action:
def index
@products = Shopsense.fetch
end
Upvotes: 1
Reputation: 8318
Instance variables don't belong in a model. So you can not use @products
there. Put it back into the controller and you are fine.
Upvotes: 1