I have the following code in my model for a method to check if a particular email address exists for a branch:
def does_email_exist(email, branch_id)
if Person.for_branch(branch_id).where(:email => email).count == 0
return true
else
return false
end
end
However, when I call it from the Rails Console, I get the following error :
NoMethodError: undefined method `does_email_exist' for #<Class:0x007fdcb9fb8ab8>from
/Users/mkv/.rbenv/versions/2.1.3/lib/ruby/gems/2.1.0/gems/activerecord-4.1.6/lib/active_record/dynamic_matchers.rb:26:in `method_missing'
I have reloaded the console after adding the method.
This seems more like a class method than an instance method, try renaming your method to
def self.does_email_exist(email, branch_id)
Person.for_branch(branch_id).where(email: email).exists?
end
And yea I trimmed the method a bit, didn't need to be that long.
Related
I can't call the run method in a class called MySqliteRequest. When I call the method,the error is going out.
in `main': undefined method `run' for nil:NilClass (NoMethodError)
Here some methods of MySqliteRequest
class MySqliteRequest
def print
puts "Type Of Request #{#type_of_request}"
end
def run
print
end
def _setTypeOfRequest(new_type)
if(#type_of_request == :none or #type_of_request == new_type)
#type_of_request = new_type
else
raise "Invalid: type of request already set #{#type_of_request} (new type => #{new_type}"
end
end
end
And main method ↓
def _main()
request = MySqliteRequest.new
request = request.from('nba_player_data.csv')
request = request.select('name')
request = request.where('birth_state', 'Indiana')
request.run
end
_main()
At the point where you call request.run the value for request is nil. This is why you are seeing the error you're given.
This is happening because the line right above it assigns the nil value to the request variable.
You are clearly coming from another language that is not Ruby (some type of C maybe?), by how you've formatted things. It would help for you to get more familiar with Ruby and its idioms. However, best I can tell, you want to do something like this instead:
def _main
request = MySqliteRequest.new
request.from('nba_player_data.csv')
request.select('name')
request.where('birth_state', 'Indiana')
request.run
end
_main()
This assumes you've also defined (and in some cases probably overridden) these methods on your MySqliteRequest Object or Model:
from
select
where
However, please note that the way you're going about this is just completely against how Ruby and Ruby on Rails is designed to work.
Hi I have a service class which is pulling information from Hubspot.
module HubspotApi
class CompanyImporter < ApplicationService
MAX_RETRIES = 3
def initialize(company_vid)
#company_vid = company_vid
#attempt = 0
end
def service_body
imported_profile
end
private
attr_reader :company_vid, :attempt
def imported_profile
## load hubspot record over here and take other actions
end
def hubspot_record
#hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (attempt += 1) <= MAX_RETRIES
sleep 2**attempt
retry
else
#messages << 'Raise some hubspot error'
end
end
end
end
I tried calling this with an incorrect company_vid to make sure the retry works properly and I keep getting the error:
NoMethodError: undefined method `+' for nil:NilClass from `rescue in hubspot_record'
Caused by Hubspot::RequestError: Response body: {"status":"error","message":"resource not found"}
I am not sure if I am having a brain-fart here but I just cannot figure out the error here since the variable should be defined
In Ruby, local variables are defined from the moment that an assignment to them is parsed (NOT executed).
Since you are assigning to attempt, Ruby will make attempt a local variable of hubspot_record. However, since it is not initialized, it will evaluate to nil.
attempt += 1
is equivalent to
attempt = attempt + 1
And since attempt is un-initialized and evaluates to nil, this is essentially evaluating nil + 1.
If you want to use the attribute reader method, you have to make it clear to Ruby that you are intending a message send and not access a local variable. There are two ways to do this: a local variable cannot have a receiver and a local variable cannot have an argument list. So, if you add either one of those, Ruby will know it is a message send and not a local variable:
attempt()
self.attempt
Either one of those will make it clear to Ruby that you intend to call the HubspotApi::CompanyImporter#attempt method.
However, that still will not work, because you are trying to assign to and you don't actually have an attribute writer, so your next error message is going to be something like
NoMethodError: undefined method `attempt=' for HubspotApi::CompanyImporter
The way to fix this problem pre-Ruby 2.7 is to:
change attr_reader :attempt to attr_accessor :attempt
And
def hubspot_record
#hubspot_record ||= Hubspot::Company.find_by_id(company_vid.to_i)
rescue Hubspot::RequestError
if (self.attempt = attempt + 1) <= MAX_RETRIES ## This was fixed in Ruby 2.7 but for earlier versions you need to read using self and write directly.
sleep 2**attempt
retry
else
#messages << 'Raise some hubspot error'
end
end
Link for update in Ruby 2.7: https://blog.saeloun.com/2019/12/24/ruby-2-7-allows-calling-a-private-method-with-self.html
I am getting undefined method 'xyz' for #. 'xyz' is a instance method written inside ABC Class. Calling the method using delayed job although the object exists. Why I am getting this error. Please anyone help me.
Code Snippet:
device_obj.delay(run_at: 5.minutes.from_now).get_device_battery_status
In Device model:
def get_device_battery_status # Used in delayed Job
command_data = {"mode"=>"get_battery"}
self.send_command(command_data)
end
I have a chain of methods and at any time one of them could return nil based on what they're returning (a collection) and then a method on that collection will blow up because it is nil.
I'm not sure how to properly handle these cases? Should I do a if statement in each and explicitly return the method to stop the execution or what do I do?
undefined method `created_at' for nil:NilClass
# ./app/models/exercise.rb:132:in `last_placeholder_log_date'
# ./app/models/exercise.rb:136:in `placeholder_log_entries'
# ./app/models/exercise.rb:140:in `placeholder_log_entries!'
def last_placeholder_log_date(user)
self.last_log_entry(user, true).created_at.beginning_of_day
end
How do I gracefully handle the possibility if there is no last log entry?
You can use try:
def last_placeholder_log_date(user)
self.last_log_entry(user, true).try(:created_at).try(:beginning_of_day)
end
With try, it's ensured that an exception is not raised if receiver does not respond. If the receiver does not respond then the call returns nil.
Write code as :
def last_placeholder_log_date(user)
val = last_log_entry(user, true)
val.created_at.beginning_of_day unless val.nil?
end
I'm trying to learn rspec. I can't seem to test a rails controller method. When I call the method in the test, rspec just returns an undefined method error. Here is my test example
it 'should return 99 if large' do
GamesController.testme(1000).should == 99
end
and here is the error:
Failure/Error: GamesController.testme(1000).should == 99
NoMethodError:
undefined method `testme' for GamesController:Class
I do have a testme method in the GamesController. I don't understand why the test code cannot see my methods.
Any help is appreciated.
I think the correct way is this:
describe GamesController do
it 'should return 99 if large' do
controller.testme(1000).should == 99
end
end
In a rails controller spec, when you put the controller class in describe, you can use controller method to get an instance :P
Obviously, if testme method is private, you still have to use controller.send :testme
You try to test class method, but controller has instance method
You need GamesController.new.testme(1000).should == 99
Or even GamesController.new.send(:testme, 1000).should == 99, because, as I think, this is not action method, but private or protected.
Action methods are tested this way