NoMethodError (undefined method `[]' for nil:NilClass) - ruby

I have a very odd instance of this error:
NoMethodError (undefined method `[]' for nil:NilClass):
app/controllers/main_controller.rb:150:in `block in find_data_label'
app/controllers/main_controller.rb:149:in `each'
app/controllers/main_controller.rb:149:in `find_data_label'
app/controllers/main_controller.rb:125:in `data_string'
app/controllers/main_controller.rb:35:in `catch'
Whats weird is that the line 150, where it says the error is, is inside a loop and executes perfectly 11 times before it decides to error out. I am out of ideas as to why it would work fine but fail one line before what would effective be the loop where the if statement returns true.
This is the code:
def find_data_label(label)
#fields.each do |f|
puts "f[:field_data]['Title'] = #{f[:field_data]['Title']}" # <--- line 150
if f[:field_data]['Title'] == label
return f
end
end
end
And this is the output before I get the error:
f[:field_data]['Title'] = Name
f[:field_data]['Title'] = Name
f[:field_data]['Title'] = Mobile number
f[:field_data]['Title'] = Email
f[:field_data]['Title'] = Date of birth
f[:field_data]['Title'] = Gender
f[:field_data]['Title'] = Street name
f[:field_data]['Title'] = Street number
f[:field_data]['Title'] = My local Puckles store is in
f[:field_data]['Title'] = Suburb
f[:field_data]['Title'] = Postcode
Completed 500 Internal Server Error in 2047ms
Thanks in advance for any help.

One of your #fields elements doesnt contain Title in :field_data.
Try inspecting #fields before calling #fields.each:
Rails.logger.warn '-'*40
Rails.logger.warn #fields.inspect
Check the server logs to see what elements you have in #fields.

For that error, see also: http://mongoid.org/en/mongoid/docs/tips.html
e.g. maybe you're using MongoID and an older version of Ruby.

Related

Ruby - no implicit conversion of Array into String

I am getting an error when executing my test.
Failure/Error: expect(industry_sic_code).to include page.sic_code
TypeError:
no implicit conversion of Array into String
# ./spec/os/bal/company/company_filter_clean_harbors_industries_stub.rb:62:in `block (2 levels) in <top (required)>'
The Method:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
puts codes.text.to_s
end
end
end
end
The Test:
it 'Given I search for a random Clean Harbors Industry' do
#Pick a random clean industry from the file
data = CSV.foreach(file_path, headers: true).map{ |row| row.to_h }
random = data.sample
random_industry = random["Class"]
industry_sic_code = random["SIC Code"]
end
it 'Then the result has the expected SIC code' do
page = DetailPage.new(#b)
page.view
expect(industry_sic_code).to include page.sic_code
end
I have tried to implicitly change each variable to a string but it still complain about the array issue.
When I include some puts statments, I get some really wonky responses. The method itself returns the expected result.
When I used the method in the test I end up with the code gibberish below.
here are the sic codes from the method
5511
Here are the codes from the test
#<Watir::Table:0x00007fa3cb23f020>
#<Watir::Table:0x00007fa3cb23ee40>
#<Watir::Table:0x00007fa3cb23ec88>
#<Watir::Table:0x00007fa3cb23ead0>
#<Watir::Table:0x00007fa3cb23e918>
#<Watir::Table:0x00007fa3cb23e738>
#<Watir::Table:0x00007fa3cb23e580>
Your sic_code method returns subtables array, that's why you have this error. It doesn't matter that the method puts something, every method in ruby implicitly returns result of its last line, in your case it is subtables.each do ... end, so you have an array.
You need to explicitly return needed value. Not sure if I correctly understood what are you doing in your code, but try something like this:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
result = [] # you need to collect result somewhere to return it later
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
result << codes.text.to_s
end
end
end
result.join(', ')
end

Getting server error 500 on calling a method ruby

When I call a function I get the following error log;
please help decipher it.
NoMethodError (undefined method `first' for #<Matching:0x0000000875a050>):
app/mailers/matching_mailer.rb:6:in `new_matchings_for_customer'
app/models/matching.rb:133:in `block in create_matchings_from_service'
app/models/matching.rb:126:in `each'
app/models/matching.rb:126:in `create_matchings_from_service'
app/models/matching.rb:30:in `process_matchings_for_service'
app/models/payments/subscription.rb:94:in `find_matchings'
app/models/payments/subscription.rb:85:in `after_create_actions'
app/controllers/contractors/subscriptions_controller.rb:51:in `subscribe'
app/controllers/contractors/subscriptions_controller.rb:19:in `create'
EDIT 1:
First few lines of matching mailer:
class MatchingMailer < ActionMailer::Base
default from: "\"Estimate My Project\" <info#estimatemyproject.com>"
def new_matchings_for_customer(matchings, customer_id)
#customer = Customer.find(customer_id)
#matchings = Matching.find(matchings)
#category = #matchings.first.emp_request.subcategory.category
unless #customer.email.empty?
mail(to: #customer.email, subject: "#{#category.name} estimate for project in #{#customer.zip_code.county.name}, #{#customer.zip_code.state.code} #{#customer.zip_code.code}")
else
self.message.perform_deliveries = false
end
end
NoMethodError (undefined method `first' for #<Matching:0x0000000875a050>)
means that there is no method first on a Matching.
app/mailers/matching_mailer.rb:6:in `new_matchings_for_customer'
means you try to call the method first on an instance of matching in line 6 of the `app/mailers/matching_mailer.rb``
Looking at your MatchingMailer in line 6, we see hat you call first on #matching. #matching was set just the line before. Please note that the Matching.find returns one record when you pass in a single id and returns an array of records when you pass in a array of ids. In this case you pass matchings that was provided as an argument to the new_matchings_for_customer method.
It is quite obvious, that the matchings argument must be a single id. Otherwise #matchings would have return an array and an array would respond to first. Since you always call first and never care about other values in the array, it makes more sense to just load one record.
Change your MatchingMailer to:
class MatchingMailer < ActionMailer::Base
default from: '"Estimate My Project" <info#estimatemyproject.com>'
def new_matchings_for_customer(matching_id, customer_id)
customer = Customer.find(customer_id)
if customer.email.present?
matching = Matching.find(matching_id)
category = matching.emp_request.subcategory.category
mail(
to: customer.email,
subject: "#{category.name} estimate for project in #{customer.zip_code.county.name}, #{customer.zip_code.state.code} #{customer.zip_code.code}"
)
else
self.message.perform_deliveries = false
end
end
end
And ensure to only pass one matching_id when calling that method.

Undefined method when trying to square each element in array

I am trying to write a method called square_digits that squares every digit in a given number. I wrote:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.to_i
num_squared = num_to_int.each{|n| n**2}
return num_squared.join("")
end
When trying to run square_digits(3212), which should return 9414, I get the following error message:
`block in square_digits': undefined method `**' for "3":String (NoMethodError)
from `each'
from `square_digits'
from `
'
I'm not quite sure what I should do to fix it; any suggestions?
Hmm there are a few problems here:
With the input 123 it should error on:
num_to_int = number_array.to_i
With:
NoMethodError: undefined method 'to_i' for ["1","2","3"]:Array
You want:
num_to_int = number_array.map(&:to_i)
Also
num_squared = num_to_int.each{|n| n**2}
doesn't return the results of each just the original array.
So with the first fix it will just return "123"
you want:
num_squared = num_to_int.map{|n| n**2}
So the final function looks like:
def square_digits(num)
number_array = num.to_s.split("")
num_to_int = number_array.map(&:to_i)
num_squared = num_to_int.map{|n| n**2}
return num_squared.join("")
end
Although i'm confused about what you are trying to achieve.
You can also try this ;)
def square_digits(num)
num.to_s.split('').map { |n| n.to_i ** 2 }.join("")
end
Or
def square_digits(num)
num.to_s.chars.map { |n| n.to_i ** 2 }.join("")
end

What's causing this Ruby "can't convert Mongo::Cursor into Integer" error?

I am using the Mongo Ruby driver and have this block of Ruby code before and after line 171 in my code, which is apparently the source of the error below it (the query.each line is line 171):
query = get_callback.call( "databases", id )
if query.count > 0
puts query.count.inspect + " results: " + query.inspect
res = {}
query.each do |result|
puts result.inspect
end
else
puts "No results" + res.inspect
res = {}
end
The error:
1 results: <Mongo::Cursor:0x3fc15642c154 namespace='myproj.databases' #selector={"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')} #cursor_id=>
TypeError - can't convert Mongo::Cursor into Integer:
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `pack'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/bson-1.6.4/lib/bson/byte_buffer.rb:156:in `put_int'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:603:in `construct_query_message'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:466:in `send_initial_query'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:459:in `refresh'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:128:in `next'
/Users/myuser/.rvm/gems/ruby-1.9.3-p194/gems/mongo-1.6.4/lib/mongo/cursor.rb:291:in `each'
/Users/myuser/Code/myproj/my_file.rb:171:in `block in initialize'
My query object: {"_id"=>BSON::ObjectId('4fe120e4a2f9a386ed000001')}
I have not the faintest idea what's causing this. I've verified the object I'm finding exists and the query.count shows that there's a result in my Mongo::Cursor.
I've not found any examples of the issue on Google and every Mongo/Ruby on the web I've found uses an each iterator just like I do. Anyone know what's the cause of this error? I notice I also get it when trying to use to_a to cast the collection to a JSON-usable object.
For what it's worth, here's the relevant part of byte_buffer.rb is below. The line with << is line 156.
def put_int(i, offset=nil)
#cursor = offset if offset
if more?
#str[#cursor, 4] = [i].pack(#int_pack_order)
else
ensure_length(#cursor)
#str << [i].pack(#int_pack_order)
end
#cursor += 4
end
This happens when you pass nil to a Ruby Mongo driver limit() method.

Undefined method `bytesize' for #<Hash>

I'd like to store and update blogger labels to datastore in GAE.
When I run that code, I get this error:
javax.servlet.ServletContext log: Application Error
/base/data/home/apps/yet-another-problem/1.334886515480009498/WEB-INF/gems/gems/sinatra-0.9.2/lib/sinatra/base.rb:45:in `each': undefined method `bytesize' for #<Hash:0x86684c> (NoMethodError)
The Code
class Labels
class LabelData
include Bumble
ds :blog_element_labels
end
def update
response = URLFetch.get($label_url)
result = response.to_s
result_headless = result.gsub("listLabels(",'')
pure_result = result_headless.gsub(");",'')
json_to_yaml = YAML::load(pure_result)['entry']['category']
json_to_yaml.each do |label|
#label = LabelData.find(:blog_element_labels => label['term'])
#label = LabelData.create(:blog_element_labels => label['term']) if #label.nil?
end
end
end
and run by cron job does '/job'
get '/job' do
#labels = Labels.new
#labels.update
end
Where is the problem? Please teach me.
But when run cron job first time, label data was stored, even occur that error.
Could not update data.
I think your having the same problem that's been discussed here: error happens when I try "all" method in datamapper
In your case, Sinatra is trying to take the return value of #lavels.update and turn that into a string to display to the user.
Try this to see if it fixes the problem:
get '/job' do
#labels = Labels.new
#labels.update
"Labels Updated"
end
Your return value is now a string, so you shouldn't get the error.

Resources