undefined method `+#' for nil:NilClass rails after moving to mysql - mysql

I moved the database to mysql which is on VM. After moving database I started getting this error when I am trying to access or saving data to database but some models updation are working fine.
The model I am accessing has some arithmetic computations which I feel is the reason for this issue.
Error is
undefined method `+#' for nil:NilClass
I tried from rails console as well and I am getting same error with this command
Settings.all
I guess this is part of that method method
if params[:lat] and params[:lon] and params[:rad] and !params[:lat].empty? and
!params[:lon].empty? and !params[:rad].empty?
lat = params[:lat].to_f
lon = params[:lon].to_f
rad = params[:rad].to_f
ear = 6371.00
min_lat = (lat) - (rad/ear)/180.0*Math::PI;
max_lat = (lat) + (rad/ear)/180.0*Math::PI;
min_lon = (lon) - (rad/ear/Math.cos(lon*Math::PI/180.0))/180.0*Math::PI;
max_lon = (lon) + (rad/ear/Math.cos(lon*Math::PI/180.0))/180.0*Math::PI;
#settings = #settings.includes(:settings_location)
.where("settings_locations.latitude > :min_lat AND " \
"settings_locations.latitude < :max_lat AND " \
"settings_locations.longitude > :min_lon AND " \
"settings_locations.longitude < :max_lon", {
min_lat: min_lat,
max_lat: max_lat,
min_lon: min_lon,
max_lon: max_lon});
stack trace
Started POST "/settings.json" for 127.0.0.1 at 2014-04-24 13:52:53 +0200
NoMethodError - undefined method `+#' for nil:NilClass:
app/models/settings.rb:54:in `<top (required)>'
activesupport (4.0.2) lib/active_support/dependencies.rb:424:in `block in load_file'
activesupport (4.0.2) lib/active_support/dependencies.rb:616:in `new_constants_in'
activesupport (4.0.2) lib/active_support/dependencies.rb:423:in `load_file'
activesupport (4.0.2) lib/active_support/dependencies.rb:324:in `require_or_load'
activesupport (4.0.2) lib/active_support/dependencies.rb:463:in `load_missing_constant'
setting.rb:
class Settings < ActiveRecord::Base
has_one :settings_location
def to_builder
Jbuilder.new do |json|
json.location settings_location.to_builder
end
end //this line is 54

Per the comments, there seem to be only a handful of cases where you can reproduce the same error message in IRB. The first is:
foo, bar = nil, nil
foo.send("+#", bar) # undefined method `+#' for nil:NilClass
The second is:
foo = nil
+foo # undefined method `+#' for nil:NilClass
In an eval context, the latter might more look like:
foo, bar = nil, nil
eval("foo = +#{bar.inspect}") # undefined method `+#' for nil:NilClass
My personal guess is that your problem is something along the lines of the latter. Not with eval, but rather with one of its plethora of Ruby variations such as define_method. The actual call is very likely somewhere in Rail's internals and related to some uninitialized variable — perhaps MySQL is returning null where SQLite was returning something due to a recent schema change that you didn't think about?
Personally, I'd try to narrow it down step by step:
1. Comment out:
json.location settings_location.to_builder
If the error is gone, then:
2.a) Replace it with:
builder = settings_location.to_builder
json.location builder
If the error message is still the same, then:
2.b) Try
Jbuilder.new
… without a block.
The point is, you want to narrow things down to the specific method that is causing the error, and then dive into that method's code to see what is nil and shouldn't be. (Perhaps the block is missing some kind of return value?)

Related

Ruby - Trying to iterate through a hash with a nested hash (after desieralising a JSON object)

I'm quite new to Ruby and I thought I'd write a program that would call an API and deserailise the JSON object.
For reference, here is the API I am calling; https://api.exchangeratesapi.io/latest?base=GBP
I'm having trouble iterating through the hash, I get the following error:
Traceback (most recent call last):
2: from ruby-api.rb:21:in `<main>'
1: from ruby-api.rb:21:in `each'
ruby-api.rb:23:in `block in <main>': undefined method `each' for "GBP":String (NoMethodError)
Here is the code that I have so far (with comments)
#requiring the library for http client
require 'net/http'
#require the URI library
require 'uri'
#requiring the json library for deserialising JSON objects
require 'json'
#output of get request stored in a string to deserialise JSON
json_string = Net::HTTP.get(URI.parse('https://api.exchangeratesapi.io/latest?base=GBP'))
#testing output
puts "Direct output \n#{json_string}"
puts "First JSON Parse attempt\n"
JSON.parse(json_string).each do |currency, rate|
puts "#{currency} - #{rate}"
end
#parse the JSON object to a hash and iterate through it, displaying each key, value pair
puts "JSON Parse output with nested each statements \n"
JSON.parse(json_string).each do |key, value|
#however - this contains a nested hash! So a nested each do is needed.
value.each do |currency, rate|
puts "#{currency} - #{rate}"
end
end
Here's the full output for when I run the code:
Direct output
{"rates":{"CAD":1.6409680499,"HKD":9.6691560447,"ISK":152.3948565332,"PHP":63.800325678,"DKK":8.3851984951,"HUF":373.6986916727,"CZK":28.9078555786,"GBP":1.0,"RON":5.3321354371,"SEK":12.1404907631,"IDR":17442.1809197597,"INR":87.4181593576,"BRL":5.0228536133,"RUB":79.8944353978,"HRK":8.3345499467,"JPY":131.652535235,"THB":37.5506766242,"CHF":1.2255601101,"EUR":1.1230276826,"MYR":5.16064911,"BGN":2.1964175417,"TRY":7.0194845303,"CNY":8.8154304004,"NOK":11.220731091,"NZD":1.9484530294,"ZAR":18.6923465663,"USD":1.2329720928,"MXN":24.1548655174,"SGD":1.7001516087,"AUD":1.824583076,"ILS":4.2960300971,"KRW":1473.7716884721,"PLN":4.8565332135},"base":"GBP","date":"2019-10-04"}
First JSON Parse attempt
rates - {"CAD"=>1.6409680499, "HKD"=>9.6691560447, "ISK"=>152.3948565332, "PHP"=>63.800325678, "DKK"=>8.3851984951, "HUF"=>373.6986916727, "CZK"=>28.9078555786, "GBP"=>1.0, "RON"=>5.3321354371, "SEK"=>12.1404907631, "IDR"=>17442.1809197597, "INR"=>87.4181593576, "BRL"=>5.0228536133, "RUB"=>79.8944353978, "HRK"=>8.3345499467, "JPY"=>131.652535235, "THB"=>37.5506766242, "CHF"=>1.2255601101, "EUR"=>1.1230276826, "MYR"=>5.16064911, "BGN"=>2.1964175417, "TRY"=>7.0194845303, "CNY"=>8.8154304004, "NOK"=>11.220731091, "NZD"=>1.9484530294, "ZAR"=>18.6923465663, "USD"=>1.2329720928, "MXN"=>24.1548655174, "SGD"=>1.7001516087, "AUD"=>1.824583076, "ILS"=>4.2960300971, "KRW"=>1473.7716884721, "PLN"=>4.8565332135}
base - GBP
date - 2019-10-04
JSON Parse output with nested each statements
CAD - 1.6409680499
HKD - 9.6691560447
ISK - 152.3948565332
PHP - 63.800325678
DKK - 8.3851984951
HUF - 373.6986916727
CZK - 28.9078555786
GBP - 1.0
RON - 5.3321354371
SEK - 12.1404907631
IDR - 17442.1809197597
INR - 87.4181593576
BRL - 5.0228536133
RUB - 79.8944353978
HRK - 8.3345499467
JPY - 131.652535235
THB - 37.5506766242
CHF - 1.2255601101
EUR - 1.1230276826
MYR - 5.16064911
BGN - 2.1964175417
TRY - 7.0194845303
CNY - 8.8154304004
NOK - 11.220731091
NZD - 1.9484530294
ZAR - 18.6923465663
USD - 1.2329720928
MXN - 24.1548655174
SGD - 1.7001516087
AUD - 1.824583076
ILS - 4.2960300971
KRW - 1473.7716884721
PLN - 4.8565332135
Traceback (most recent call last):
2: from ruby-api.rb:21:in `<main>'
1: from ruby-api.rb:21:in `each'
ruby-api.rb:23:in `block in <main>': undefined method `each' for "GBP":String (NoMethodError)
So what's happening is that it will happily iterate through the hash but as soon as it hits the 'base' key (with a value of GBP) - it falls over.
What's the best way to resolve this?
Thanks!
You're trying to iterate over each value in the parsed JSON, which works in the same time because the value of rates is a hash, but the values for base and date are strings. There you invoke each and get the NoMethodError exception.
Try instead accessing the dates key:
JSON.parse(json_string)['rates'].each do |currency, rate|
puts "#{currency} - #{rate}"
end

Problems Parsing a Json File in Ruby

I'm pretty new to programming ruby and using json packages, I think I'm facing a typical noob-error, but I just cant find my mistake for two days now.. I've started like this:
require 'discogs-wrapper'
require 'json'
aw = Discogs::Wrapper.new("my_application", user_token: "my_user_token")
inv = aw.get_user_inventory('my_user_name', :per_page => 1, :page => 1)
p=JSON.parse(inv)
What I recieve is this:
C:/Ruby24-x64/lib/ruby/2.4.0/json/common.rb:156:in `initialize': no implicit conversion of Hashie::Mash into String (TypeError)
from C:/Ruby24-x64/lib/ruby/2.4.0/json/common.rb:156:in `new'
from C:/Ruby24-x64/lib/ruby/2.4.0/json/common.rb:156:in `parse'
from C:/Users/rtuz2th/.RubyMine2017.3/config/scratches/scratch.rb:6:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
I've already been searching your forum and I've learned that this error probably means that I do not have a correct JSON-file (although it comes straight from the discogs-api, I basically thought these guys know what they do). So what I tried next was
require 'discogs-wrapper'
require 'json'
aw = Discogs::Wrapper.new("my_application", user_token: "my_user_token")
inv = aw.get_user_inventory('my_user_name', :per_page => 1, :page => 1)
inv = inv.to_json
p=JSON.parse(inv)
So at least, my code runs without any errors now. But when I try to refer to any information in inv, I just get empty responses. inv (without the .to_json looks like this:
{"pagination"=>
{"per_page"=>1,
"items"=>13692,
"page"=>1,
"urls"=>
{"last"=>
"URL containing tokens",
"next"=>
"URL containing tokens"},
"pages"=>13692},
"listings"=>
[{"status"=>"Draft",
"original_price"=>
{"curr_abbr"=>"EUR",
"formatted"=>"\u20AC10.46",
"value"=>10.46,
"curr_id"=>3},
"weight"=>230.0,
"original_shipping_price"=>
{"curr_abbr"=>"EUR",
"formatted"=>"\u20AC5.90",
"value"=>5.9,
"curr_id"=>3},
"price"=>{"currency"=>"EUR", "value"=>10.46},
"allow_offers"=>true,
"uri"=>"https://www.discogs.com/sell/item/437965910",
"sleeve_condition"=>"Very Good Plus (VG+)",
"format_quantity"=>1,
"id"=>437965910,
"shipping_price"=>{"currency"=>"EUR", "value"=>5.9},
"posted"=>"2017-02-07T23:43:01-08:00",
"ships_from"=>"Germany",
"in_cart"=>false,
"comments"=>"",
"seller"=>
{"username"=>"zweischeiben.de",
"stats"=>{"rating"=>"100.0", "total"=>143, "stars"=>5.0},
"uid"=>3359767,
"url"=>"https://api.discogs.com/users/zweischeiben.de",
"html_url"=>"https://www.discogs.com/user/zweischeiben.de",
"shipping"=>
"(Lots of information about shipping, cut just cut it out)"
"payment"=>"Bank Transfer, PayPal",
"avatar_url"=>
"(cut out url)",
"resource_url"=>"https://api.discogs.com/users/zweischeiben.de",
"id"=>3359767},
"condition"=>"Near Mint (NM or M-)",
"release"=>
{"thumbnail"=>
"(cut out url)",
"description"=>"Steamhammer - Mountains (LP, Album, RE)",
"artist"=>"Steamhammer",
"format"=>"LP, Album, RE",
"resource_url"=>"https://api.discogs.com/releases/7303333",
"title"=>"Mountains",
"year"=>0,
"id"=>7303333,
"catalog_number"=>"201.006, 0201.006"},
"resource_url"=>"https://api.discogs.com/marketplace/listings/437965910",
"audio"=>false,
"external_id"=>"3, 16",
"location"=>"T52574"}]}
But if I now try to refer to eg the location:
require 'discogs-wrapper'
require 'json'
aw = Discogs::Wrapper.new("my_application", user_token: "my_token")
inv=aw.get_user_inventory('my_username', :per_page => 1, :page => 1)
inv=inv.to_json
p=JSON.parse(inv)
puts p[location]
I'm just getting an error like this
C:\Ruby24-x64\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) C:/Users/rtuz2th/.RubyMine2017.3/config/scratches/scratch.rb
C:/Users/rtuz2th/.RubyMine2017.3/config/scratches/scratch.rb:9:in `<top (required)>': undefined local variable or method `location' for main:Object (NameError)
from -e:1:in `load'
from -e:1:in `<main>'
Process finished with exit code 1
or an empty response. I'm trying to solve this for two days now, but I'm absolutely out of ideas. Thanks for your help in advance!
inv = inv.to_json
p = JSON.parse(inv)
The above is a noop. Use inv as is, it’s a hash already.
puts p[location]
You cannot just lookup whatever key located deeply in the tree hierarchy or you hash. You hash has stings as keys, it has a two top-level elements, 'pagination' and 'listings', the latter is an array, and each element of this array is a hash having location key.
While you were cutting the long value, you dropped the ending comma, making me unable to copy-paste the input and provide the exact answer.

Getting a JavaScript Error when calling prompt method from page-object-gem

Scenario: Testing with prompt popups
Given I am on the frames page
When I popup the prompt and enter "Jared Gatorboy"
SyntaxError: missing ; before statement (Selenium::WebDriver::Error::JavascriptError)
./features/support/pages/frames_page.rb:35:in `block in prompt_value'
./features/support/pages/frames_page.rb:34:in `prompt_value'
./features/step_definitions/web01_steps.rb:35:in `block (2 levels) in <top (required)>'
./features/step_definitions/web01_steps.rb:34:in `/^I popup the prompt and enter "(.*?)"$/'
features/web01.feature:20:in `When I popup the prompt and enter "Jared Gatorboy"'
Then the message from the prompt should read "enter your name"
And the default value from the prompt should be "John Doe"
./features/support/pages/frames_page.rb
def prompt_value(value)
in_frame(:id => 'frame_3') do |frame|
#prompt_response = prompt(value, frame) do
button_element(:id => 'prompt_button', :frame => frame).click
end
end
#prompt_response
end
./features/step_definitions/web01_steps.rb
When(/^I popup the prompt and enter "(.*?)"$/) do |value_to_enter|
on_page(FramesPage) do |page|
#prompt_response = page.prompt_value(value_to_enter)
end
end
App URL
Can you tell me what browser and driver you are using? In the page-object test suite there is a test that uses this page. Here is the step definition
When /^I trigger a prompt within a frame$/ do
#page.in_frame(:id => 'frame_3') do |frame|
#msg = #page.prompt("Cheezy", frame) do
#page.button_element(:id => 'prompt_button', :frame => frame).click
end
end
end
It looks to be the identical logic you have in your steps and the tests work with the latest firefox using both selenium-webdriver and watir-webdriver as the driver.

List Files: Backend Error (No error code) Google Drive SDK

we've built a web app that automatically indexes and saves email attachments directly to Google Drive based on user-defined business rules. We're seeing failures when syncing some Google Drive accounts and can't figure out what the problem is.
This is the error:
List Files Error: Backend Error
/mnt/opt/openera/current/app/models/cloud_account/google_drive.rb:299:in 'list_files'
/mnt/opt/openera/current/app/models/cloud_account/google_drive.rb:220:in 'do_discover_files'
/mnt/opt/openera/current/app/models/cloud_account/base.rb:304:in 'discover_files'
/mnt/opt/openera/current/app/workers/worker/file_synchronizer.rb:10:in 'perform'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/processor.rb:45:in 'block (3 levels) in
process'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:109:in 'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:109:in 'block in in
voke'
/mnt/opt/openera/current/lib/sidekiq_repeat_jobs/middleware/server/repeat_jobs.rb:36:in 'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:111:in 'block in in
voke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/server/timeout.rb:14:in 'cal
l'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:111:in 'block in in
voke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/server/active_record.rb:6:in
'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:111:in 'block in in
voke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/server/retry_jobs.rb:49:in '
call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:111:in 'block in in
voke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/server/logging.rb:11:in 'blo
ck in call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/logging.rb:22:in 'with_context'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/server/logging.rb:7:in 'call
'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:111:in 'block in in
voke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:114:in 'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/middleware/chain.rb:114:in 'invoke'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/processor.rb:44:in 'block (2 levels) in
process'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/processor.rb:80:in 'stats'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/sidekiq-2.6.5/lib/sidekiq/processor.rb:43:in 'block in process'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in 'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in 'public_send'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/calls.rb:23:in 'dispatch'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/future.rb:18:in 'block in initiali
ze'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/internal_pool.rb:48:in 'call'
/mnt/opt/openera/current/vendor/bundle/ruby/1.9.1/gems/celluloid-0.12.4/lib/celluloid/internal_pool.rb:48:in 'block in c
reate'
UPDATE: Here is the actual code from our senior dev.
dev here (ffoeg) adding actual code invoked:
def list_files
pageToken = nil
params = {'maxResults' => 65535, 'q' => 'trashed = false'}
files = []
drive = session.discovered_api("drive", "v2")
while true do
call_params = pageToken.blank? ? params : params.merge('pageToken' => pageToken)
result = session.execute(api_method: drive.files.list, parameters: call_params)
if result.status == 200
files += result.data.items
break if result.data['nextPageToken'].blank?
pageToken = result.data['nextPageToken']
else
raise "List Files Error: #{result.data['error']['message']}"
end
end
files
end
UPDATING AGAIN:
We updated our code to get the exact error - here it is:
List Files Error: {"errors"=>[{"domain"=>"global", "reason"=>"backendError",
"message"=>"Backend Error"}], "code"=>503, "message"=>"Backend Error"}
The problem is the value of maxResults. It is far too large and will cause the request to time out. Unfortunately, a "safe" value is very small, about ~200 results per page. You can go larger, but results will vary based on the user. Users with smaller corpuses will probably work fine with larger page sizes, but people with larger corpuses appear to be more sensitive. Well, at least based on some very quick/informal testing on a few of my accounts.
FWIW, I remember things working better with larger page sizes. Will check if anything changed that might constrain things more than expected.

How to save database results to text file in Ruby

I am trying to take the results of a query to a db and save them to a csv file. Here is my current Ruby script.
#! /usr/bin/ruby
require 'rubygems'
require 'mysql'
require 'date'
# need mysql queries here / use mysql2 calls
db_con = Mysql.new("localhost", "root", "", "msd")
date_results = db_con.query("SELECT CONCAT(CONVERT(date_format(dd.date, '%b-%e'),char),'\\n') AS date
FROM msd.date_dim dd LEFT OUTER JOIN msd.results cs
ON dd.id = cs.date_id
GROUP BY
dd.date")
# create new xml file and insert header
open('test_trend.xml', 'w') do |f|
date_results.each_hash do |f|
f.puts "#{f['date']}"
end
end
I get the following error. Line 23 is the date_results.each_hash line.
so_test.rb:24:in `block (2 levels) in <main>': private method `puts' called for {"date"=>"Jun-12\n"}:Hash (NoMethodError)
from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.9/lib/mysql.rb:686:in `call'
from /Users/pierce/.rbenv/versions/1.9.2-p290/lib/ruby/gems/1.9.1/gems/ruby-mysql-2.9.9/lib/mysql.rb:686:in `each_hash'
from so_test.rb:23:in `block in <main>'
from so_test.rb:22:in `open'
from so_test.rb:22:in `<main>'
Any advice is appreciated. Thanks.
In your nested blocks, you're overriding the f variable. Instead, try something like:
# create new xml file and insert header
open('test_trend.xml', 'w') do |f|
date_results.each_hash do |hash|
f.puts "#{hash['date']}"
end
end