No implicit conversion of nil into String on MessageVerifier - ruby-on-rails

Recently I received new project (backend of iOS app, actually) that works on Ruby (Rails).
I have a part of code in model (user):
155: def self.create_access_token(user)
156: verifier.generate(user.id)
157: end
After some action that indirectly uses that part of code, in "Passenger" output I see following error that terminates everything:
TypeError (no implicit conversion of nil into String):
app/models/user.rb:156:in `create_access_token'
app/models/user.rb:139:in `access_token'
app/controllers/mailing_controller.rb:68:in `send_charts'
verifier is an instance of ActiveSupport::MessageVerifier
I'm totally sure that user.id contains valid value (I've tested it with $stderr.puts)
I'm completely new to this language, it's hard for me to figure out why this error appears. Hope someone can help.
Thanks!

Well, it may the case user_id is nil. Anyway please check out rubyonrails api and verify generate method.
We can actually dig inside generate method. Use pry-rails gem for easy debugging.

Most likely you did not set the access_token_secret in secrets.yml.

Related

Unable to use active record time methods inside ruby on rails 5.0 model

I'm currently unable to use any of the active support time methods inside my ruby on rails 5.0 model like the following:
5.seconds
2.days
10.minutes
throws an error:
NoMethodError: undefined method `seconds' for AS::Duration:0x007f97a5903b90 #value=5, #parts=[[:seconds, 5]] Did you mean? send
EDIT: here is the actual code causing an issue.
ReminderJob.set(wait: 5.seconds).perform_later(self.user.id)
Even tho I can see people using the below code fine and it works
UserReminderJob.set(wait: 1.week).perform_later user
However, it works in my console and in my controllers and views.
The error message states that the object is AS::Duration:0x007f97a5903b90, NOT an integer -- therefore the example of 5.seconds will not reproduce the problem.
This is also unusual, since 5.seconds will normally return an ActiveSupport::Duration object, not AS::Duration.
I would therefore hazard a guess that you're actually using the as-duration ruby gem rather than built-in rails behaviour. This extends the the Integer class in a different way, and returns an object that doesn't behave like an integer.
I think that an actual reproduction of your error could be achieved with: 5.seconds.seconds. In standard rails, this works fine (and returns the same value as 5.seconds), since ActiveSupport::Duration instances behave like Integers. But with this gem, it fails with the above error.

no implicit conversion of User into String Error only in rails app

the above code works when I just run it with ruby
but when I run it in my rails app I get the above error
Well, actually it seems like your #user object has been set before. Maybe you have set it within some before_filter?
The assignment using ||= only reads the file when #user is nil, otherwise, it will ignore the assignment at all.

rails dot notation no longer works for accessing hash values gives NoMethodError

I'm using rails 5 with ruby 2.3.3 . Today I added a gem, there was a version conflict so I took the gem out. Since then dot notation such as hash.test no longer works. It gives NoMethodError: private method test called for {:test=>"value"}:Hash
How can I access hashes with dot notation again?
Whatever you're using to use dot-notation to access a hash is probably using method_missing to trap your dot-notation method calls. But everything has a test method because Kernel#test exists and everything includes Kernel; also, pretty much everything in Kernel is private because Kernel is where methods go that we want to pretend are functions. For example:
> 'pancakes'.test
NoMethodError: private method `test' called for "pancakes":String
I suspect that you problem is your choice of :test as hash key.

Rails- upgrading to ruby 2.2.2 - no implicit conversion of Array into String (TypeError)

very new to ruby and rails.. Ive been working on a project, that simply reads in files and parses them to store into a database. Project was running fine, however running the code after an update to ruby 2.2.2 , I received an error that wasn't previously there:
in `foreach': no implicit conversion of Array into String (TypeError)
Here is the snippet of the foreach thats causing an error: (let me know if more code is necessary).
def parse(file_name)
File.foreach(file_name).with_index do |line, line_num|
puts "\nLine #{line_num}: #{line}"
Does anyone know whats going on?
Thank you
EDIT: Sorry it was a snippet! Im calling this ruby code into my rails Test called "parse_log_file_test"
require File.dirname(__FILE__) + '/../test_helper'
class ParseLogFileTest < ActiveSupport::TestCase
filename = Array.new
Dir.glob('database/oag-logs/*.log').each do |log_file|
filename.push(log_file)
end
parser = ParseLogFile.new
parser.parse(filename)
test 'parse' do
parser = ParseLogFile.new
filename.each do |log_file|
begin
parser.parse(log_file)
rescue
puts"ERROR: Unable to parse line #{log_file}"
end
end
assert true
end
end
I'm guessing you omitted the end to your function, but if you don't have it, you need it.
This error indicates that the argument passed to parse as file_name is an array instead of a string.
However, if that's the case, it fails the same on e.g. Ruby 1.8.4:
File.foreach([]).with_index do |line, line_num|
puts "\nLine #{line_num}: #{line}"
end
Output:
TypeError: can't convert Array into String
from (irb):1:in `foreach'
from (irb):1:in `with_index'
from (irb):1
from :0
Thus my guess is that the code that produces the value you pass to parse returned a string in your previous Ruby version and returns an array in 2.2.2.
In your case, the error is caused by the first invocation of parser.parse(...), right above the test 'parse' do line, not by the invocation inside the test method. I guess you put that invocation there after the migration, probably to debug a problem. But you are passing a different argument to the first invocation than to the invocation inside the test method, so it fails for a different reason than the one in the test method.
To see what Error is caused inside your test, simply remove the lines
rescue
puts"ERROR: Unable to parse line #{log_file}"
(Keep the end or you'll have to remove the begin, too.)
This way, an Error will hit the test runner, which will usually display it including message and stack trace.
Agreed with the poster above that you are most likely missing quotation marks. It should have nothing to do with 2.2.2 though, probably you are copy-pastying your file name differently this time around.
So apparently this is an issue with upgrading to ruby 2.2.2 on windows. After getting past this error, I only encountered more errors.. nokogiri..etc
I have recently got a mac and the errors went away.

How to extend the String class in a command line app?

I primarily work in Rails and I'm using a command line data conversion gem, "Mongify" and I am stumped about how to extend core classes in a Ruby cli app.
I want to extend the String class with an .is_date? method to check whether a string can be converted to a Date. I've got it working in the Rails Console,
I added a string.rb file to lib/ext with the following;
class String
def is_date?
begin
return true if Date.parse(self)
rescue
#do nothing
end
return false
end
end
Then in a Rails console I do a require 'ext/string' and it will work.
But I can't figure out how to get it to work in the Mongify cli app. I copied string.rb into the lib folder of the gem and I've tried adding require 'string' to a number of different files in the gem, but I keep getting undefined method errors.
Can someone point me in the right direction?
How about you require it from lib/mongify.rb like so:
require 'string/extensions.rb'
And then put your code in lib/string/extensions.rb
Let us know the exact undefined method errors you're getting in case this isn't the solution.
To help you with the debugging exercise that would give you the answer you need. Start by putting a breakpoint right before the place of the function call.
In the debugger, load the required document and then step past your breakpoint to the next one after the call has occurred.
Once you have this working, then start earlier in the stack trace – in a file that loaded before that one. Keep moving backwards until you get to a sufficiently early part in the load process of the gem, and make that be the place you load your code.

Resources