trouble using an api on heroku from a rails app - ruby-on-rails

for a project at school I am trying to use the Bandsintown api to display upcoming concerts for artists that a user follows on my site. I am able to use the api the way I want to in development but when it comes to my heroku site in production nothing displays and I receive no errors, in fact I just receive an empty array. Perhaps you need permission from Bandsintown to use their api on heroku? I tried contacted them but have not heard a response yet.
My question, why am I able to get a response from Bandsintown on development but not in production? New to web dev in general, so I haven't come across this before..
Here is my code:
calendar_controller.rb
class CalendarController < ApplicationController
require 'uri'
def index
#user = current_user
#hash_version_array = []
#user.follows.each do |follow|
response = HTTParty.get("http://api.bandsintown.com/artists/#{URI.escape(follow.artist_name)}/events/search.json?api_version=2.0&app_id=#{app_id}&location=use_geoip")
#hash_version = JSON.parse(response.body)
#hash_version_array << #hash_version if #hash_version != []
end
#hash_version_array
end
end
calendar/index.html.erb
<h1><%= #user.name %>'s Calendar</h1>
<div>
<h4 class="inline"><%= link_to "Calendar" %></h4>
<h4 class="inline"><%= link_to "List" %></h4>
<h4 class="inline"><%= link_to "Map" %></h4>
</div>
<br>
<% #hash_version_array.each do |date| %>
<h3 class="artist_name"><%= date[0]["formatted_datetime"] %></h3>
<% date[0]["artists"].each do |info| %>
<h1 class="artist_name"><%= info["name"] %></h1>
<br>
<%= image_tag("#{info['thumb_url']}", class: 'artist_img') %>
<% end %>
<br>
<br>
<%= date[0]["venue"]["name"] %>
<br>
<%= date[0]["formatted_location"] %>, <%= date[0]["venue"]["country"] %>
<br>
Tickets <%= date[0]["ticket_status"].titleize %> <%= link_to("Buy", "#{date[0]['ticket_url']}") %>
<br>
<hr class="artists_hr">
<% end %>
Response from Bandsintown while working in development:
From: /Users/jasonquaccia/Sites/code/projects/capstone/the-music-project/app/controllers/calendar_controller.rb # line 15 CalendarController#index:
4: def index
5: #user = current_user
6: #hash_version_array = []
7:
8: #user.follows.each do |follow|
9: response = HTTParty.get("http://api.bandsintown.com/artists/#{URI.escape(follow.artist_name)}/events/search.json?api_version=2.0&app_id=el_proyecto_de_la_musica&location=use_geoip")
10: #hash_version = JSON.parse(response.body)
11:
12: #hash_version_array << #hash_version if #hash_version != []
13: end
14:
=> 15: binding.pry
16: #hash_version_array
17: end
[1] pry(#<CalendarController>)> #hash_version_array
=> [[{"id"=>10847723,
"title"=>"Metallica # AT & T Park in San Francisco, CA",
"datetime"=>"2016-02-06T19:00:00",
"formatted_datetime"=>"Saturday, February 6, 2016 at 7:00PM",
"formatted_location"=>"San Francisco, CA",
"ticket_url"=>"http://www.bandsintown.com/event/10847723/buy_tickets?app_id=el_proyecto_de_la_musica&artist=Metallica&came_from=67",
"ticket_type"=>"Tickets",
"ticket_status"=>"available",
"on_sale_datetime"=>"2015-11-06T10:00:00",
"facebook_rsvp_url"=>"http://www.bandsintown.com/event/10847723?app_id=el_proyecto_de_la_musica&artist=Metallica&came_from=67",
"description"=>"CBS RADIO's The Night Before with Metallica and Cage the Elephant",
"artists"=>
[{"name"=>"Metallica",
"mbid"=>"65f4f0c5-ef9e-490c-aee3-909e7ae6b2ab",
"image_url"=>"https://s3.amazonaws.com/bit-photos/large/4304043.jpeg",
"thumb_url"=>"https://s3.amazonaws.com/bit-photos/thumb/4304043.jpeg",
"facebook_tour_dates_url"=>"http://www.bandsintown.com/Metallica/facebookapp?came_from=67",
"facebook_page_url"=>nil,
"tracker_count"=>2341049,
"url"=>"Metallica",
"website"=>"http://metallica.com"}],
"venue"=>{"name"=>"AT & T Park", "city"=>"San Francisco", "region"=>"CA", "country"=>"United States", "latitude"=>37.7784059, "longitude"=>-122.3894401}}]]

Found out why I am not getting anything while in production on Heroku, has to do with location=use_geoip on this line:
response = HTTParty.get("http://api.bandsintown.com/artists/#{URI.escape(follow.artist_name)}/events/search.json?api_version=2.0&app_id=#{app_id}&location=use_geoip")
This works locally because it can reference my location and then search Bandsintown for the correct information. However, on Heroku it does not know how to correctly reference a location. Therefore I don't receive any results.

Related

Template::Error undefined method `[]' for nil:NilClass

Hello I have a Rails application in production, and recently i started getting totally random errors on the loading of the show method of my "complaints" controller .
My "complaints" table has a one-to-one relationship with "interactions" table, you can create an interaction then create a complaint.
I display my data in a table on complaints#index, then I click on a row to get to complaints#show
I get this error :
ActionView::Template::Error (undefined method `[]' for nil:NilClass):
7: <div class="uk-width-expand#m">
8: <h1 class="uk-heading-primary">
9: <%# <%= link_to 'Retour à l\'interaction', interaction_path(#variables[:complaint].interaction, search: #params[:search]), class: 'uk-button uk-button-default uk-margin-right' %>
10: <%= I18n.t("kind.#{#variables[:complaint].kind}") %>
11: <% if #variables[:complaint].interaction.date.present? %>
12: - <%= #variables[:complaint].interaction.date.strftime('%d/%m/%Y') %>
13: <% end %>
app/views/complaints/show.html.erb:10:in `_app_views_complaints_show_html_erb__763547916_154685640'
But this error appears totaly randomly. That means if I refresh the page, it may launch this time. So because of this, i can't understand where this error comes from, most of the time there is no error, but I get complaints from the app users saying they are really bothered.
Here is my controller show method :
def show
complaint = Complaint.find_by(id: params[:id])
if complaint.blank?
redirect_to complaints_path
return
end
interaction = Interaction.find(complaint.interaction.id)
result = DetailCommande.execute_procedure "p_detail_commande", interaction.do_piece, interaction.do_type
contenu_commande = DetailCommande.execute_procedure "p_contenu_commande", interaction.do_piece, interaction.do_type
#variables = { complaint: complaint, detail_commande: result[0], contenu_commande: contenu_commande }
#params = { search: params[:search] }
end
Here is the part of my complaints#show view that causes trouble :
<div class="uk-flex-middle uk-margin-small" uk-grid>
<div class="uk-width-expand#m">
<h1 class="uk-heading-primary">
<%= link_to 'Retour à l\'interaction', interaction_path(id: params[:id], search: #params[:search]), class: 'uk-button uk-button-default uk-margin-right' %>
<%= I18n.t("kind.#{#variables[:complaint].kind}") %>
<% if #variables[:complaint].interaction.date.present? %>
- <%= #variables[:complaint].interaction.date.strftime('%d/%m/%Y') %>
<% end %>
</h1>
</div>
<div class="uk-width-auto#m">
<% if #variables[:complaint].control.present? %>
<button class="uk-button uk-button-default" disabled>Contrôle</button>
<% else %>
<a href="#modal-control-<%= params[:id] %>" class="uk-button uk-button-warning" uk-toggle>Contrôle</a>
<% end %>
<%= link_to 'Modifier', edit_complaint_path(id: #variables[:complaint].id, search: #params[:search]), class: 'uk-button uk-button-primary' %>
<%= link_to 'Supprimer', complaint_path(#variables[:complaint], search: #params[:search]), method: :delete, data: {confirm: 'Êtes-vous sûr ?'}, class: 'uk-button uk-button-danger' %>
</div>
</div>
And here is a screen of my page when it actually loads. Just simple data display
I don't know if i provided enough informations, but thank you in advance for your help
I think that your application is running on 2 servers , sharing the load by load balancer.
I think so because of the following 2 cases:
See line no. 9 of your log i.e.
9: <%# <%= link_to 'Retour à l\'interaction', interaction_path(#variables[:complaint].interaction, search: #params[:search]), class: 'uk-button uk-button-default uk-margin-right' %>
and your html file does not contains this code, this are some changes in show.html i.e.
<%= link_to 'Retour à l\'interaction', interaction_path(id: params[:id], search: #params[:search]), class: 'uk-button uk-button-default uk-margin-right' %>
This error gone on page refresh, it means that 1 server contains correct code and 1 contains wrong code, so when the request goes on server 1, it displays the page and when it goes on server2, it gives error.
As per the logs, I think that complaint.kind is empty.

My Rails app is not saving data to the database

I am currently creating a rails form. Up until now it has been passing data to the database with ease. Recently, however it no longer finds any of the data I need in the database, it can only find the user table and none of the connected tables.
Here is a partial of my form:
<h1>Energy Assistance Application</h1>
<br />
<%= form_for(#user) do |f| %>
<%= render 'county_fields', f: f%>
<%= render 'contact_info_fields', f: f %>
<%= render 'household_members_fields', f: f%>
<%= render 'household_type_fields', f: f%>
Here is part of my controller:
def create
addresses = params[:addresses].permit([:county]).to_h
contact_info = params[:contact_info].permit(params[:contact_info].keys).to_h
household = params[:household_type].permit([:house_type]).to_h
household_members = member_params
utilities = utility_params
dhis = dhi_params
#workflow = CreatesUser.new(address_info: addresses,
contact: contact_info, household: household, members: household_members, utilities: utilities, dhis: dhis)
#workflow.create
redirect_to users_path
end
CreatesUser:
def initialize(address_info: [], has_mail: false, contact: [], household: [], members: [],
utilities: [], dhis: [])
#address_info = address_info
#contact = contact
#household = household
#members = members["household_members_attributes"]
#utilities = utilities["utilities_attributes"]
#dhis = dhis["dhis_attributes"]
end
def build
self.user = User.new(startdate: Time.zone.today)
user.addresses = get_addresses
user.contact_info = get_contact
user.household_type = get_household
user.household_members = get_members
user.utilities = get_utilities
user.dhis = get_dhis
user
end
def create
build
result = user.save
result ? print("Saved!\n") : print("Failed!\n")
end
My index.html.erb:
<h1>All Users</h1>
<% #users.each do |user|%>
<%= user.utilities%>
<ul>
<li>County:
<% user.addresses.each do |address|%>
<%=address.county%>
<%end%>
</li>
<% if !user.contact_info.nil? %>
<li>Phone: <%= user.contact_info.phone%></li>
<li>Phone Type:<%= user.contact_info.phone_type%></li>
<li>Email: <%= user.contact_info.email%></li>
<%end%>
<li>Household: <%= user.household_type.house_type%></li>
</ul>
When the workflow creates, it saves successfully, but when I run my index I get this error:
Completed 500 Internal Server Error in 19ms (ActiveRecord: 1.1ms)
ActionView::Template::Error (undefined method `house_type' for nil:NilClass):
12: <li>Phone Type:<%= user.contact_info.phone_type%></li>
13: <li>Email: <%= user.contact_info.email%></li>
14: <%end%>
15: <li>Household: <%= user.household_type.house_type%></li>
16: </ul>
17:
18: <h3> Household Members </h3>
app/views/users/index.html.erb:15:in `block in _app_views_users_index_html_erb___590344624549979162_70244223831340'
I do not know why this is happening, even when I go back to older branches that used to work, they also fail here.
Thank you for any help you can give me. If you need more info, I will happily give it to you.
I think your problems in your form. Recheck your params ( household_type ), it must have a value when submit.
And another way, if you want update difference model based on current model, you should use Active Record Nested Attributes

Spree commerce taxonomies error

undefined method `each' for nil:NilClass
<% max_level = Spree::Config[:max_level_in_taxons_menu] || 1 %>
<nav id="taxonomies" class="sidebar-item" data-hook>
<% #taxonomies.each do |taxonomy| %>
<% unless taxonomy.name == 'Tags' %>
<h6 class="taxonomy-root"><%= Spree.t(:shop_by_taxonomy, :taxonomy => taxonomy.name) %></h6>
<%= taxons_tree(taxonomy.root, #taxon, Spree::Config[:max_level_in_taxons_menu] || 1) %>
This is the error i am getting and this is the code i updated to taxonomies.each.to_a not sure if that is right and how do i update the code so the server will run the new code instead of the older code?
Here is the updated code
<% max_level = Spree::Config[:max_level_in_taxons_menu] || 1 %>
<nav id="taxonomies" class="sidebar-item" data-hook>
<% #taxonomies.each.to_a do |taxonomy| %>
<% cache [I18n.locale, taxonomy, max_level] do %>
<h6 class='taxonomy-root'><%= Spree.t(:shop_by_taxonomy, :taxonomy => taxonomy.name) %></h6>
<%= taxons_tree(taxonomy.root, #taxon, max_level) %>
<% end %>
<% end %>
</nav>
Looks like what you're doing is forcing a nil object to an array, which will work, yt isn't an ideal solution. You can wrap the whole thing in this:
<% if #taxonomies && #taxonomies.any? %>
#your code goes here
<% end %>
...which will check for the presence of a taxonomies variable and make sure it isn't an empty array before running your code. As far as getting the code on the server goes, you'll have to post more info about your deployment setup and version control to answer that question.

Display products from ShopSense API

How do I display products from the ShopSense API in Rails using shopsense-ruby?
JSON.parse(response)["products"] is returning nil:
NoMethodError in Main#index
Showing /home/dev/demo-shopsense/app/views/shared/_shopsense.html.erb where line #3 raised:
undefined method `any?' for nil:NilClass
Extracted source (around line #2):
<div class="custom_widget">
<% if #products.any %>
<% #products.each do |product| %>
<div class="product">
<%= image_tag product['image']['url'] %>
<p><%= product['name'] %></p>
main_controller.rb:
class MainController < ApplicationController
def index
client = Shopsense::API.new('partner_id' => 'uid0000-0000000-00')
response = client.get_looks("New")
#products = JSON.parse(response)["products"]
end
end
shared/_shopsense.html.erb:
<div class="custom_widget">
<% if #products.any? %>
<% #products.each do |product| %>
<div class="product">
<%= image_tag product['image']['url'] %>
<p><%= product['name'] %></p>
</div>
<% end %>
<% end %>
</div>
I've set up a simple demo app demo-shopsense that should be easy to get up and running.
The parsed response of your request looks like this:
{"totalCount"=>"536121",
"looks"=>
[{"id"=>"12328367",
"title"=>"black",
...
As you can see instead of 'products' we have 'looks'.
#products = JSON.parse(response)["looks"]
When you are working with external services, it's very important to find out the exact format of the response.
EDIT:
I think in this case you actually need to use 'search' method on the client instead of 'get_looks', if you want to get products.

How to map Amazon Products API to Rails?

I'm trying to fetch products from the Amazon Products API (using https://github.com/hakanensari/vacuum/) and display them in my Rails app. But how do I bring the product names and photos into my views?
Currently getting:
ActionView::Template::Error (undefined method `image' for #<Array:0x88486aec>):
2: <% if #products.any? %>
3: <% #products.each do |product| %>
4: <div class="product">
5: <%= link_to image_tag(product.image.url), product.url %>
6: <%= link_to product.name, product.url %>
7: </div>
8: <% end %>
main_controller.rb:
class MainController < ApplicationController
def index
request = Vacuum.new('GB')
request.configure(
aws_access_key_id: 'ABCDEFGHIJKLMNOPQRST',
aws_secret_access_key: '<long messy key>',
associate_tag: 'lipsum-20'
)
params = {
'SearchIndex' => 'Books',
'Keywords'=> 'Ruby on Rails'
}
#
# NOT SURE WHERE TO TAKE IT FROM HERE
#
raw_products = request.item_search(query: params)
#products = raw_products.to_h
product = OpenStruct.new(#products)
end
end
index.html.erb:
<% if #products.any? %>
<% #products.each do |product| %>
<div class="product">
<%= link_to image_tag(product.image.url), product.url %>
<%= link_to product.name, product.url %>
</div>
<% end %>
<% end %>
You are getting the error because raw_products isn't an array. AS par vacuum documentation, you will either have to convert it to hash by raw_products.to_h or You can also pass the response body into your own parser for some custom XML heavy-lifting:
MyParser.new(raw_products.body)
So you have to first parse the the response properly before consuming it.
You can just do following:
#products = raw_products.to_h
product = OpenStruct.new(#products)

Resources