in `_main': undefined method `run' for nil:NilClass (NoMethodError) - ruby-on-rails

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.

Related

NoMethodError: undefined method `+' for nil:NilClass for variable in private method

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

undefined method `request' for true:TrueClass

I have an app structure with nested routes in which a proposal belongs to a request and a request has many proposals.
When I execute a send_proposal method, I am trying to get it to update the status of the request to which that proposal belongs, but I am getting an error that says undefined method 'request' for true:TrueClass.
My route for this method (not that I think it matters) is:
put "proposal/:id/send_proposal" => "proposals#send_proposal", as: "send_proposal"
Here is my send_proposal method, as found in my proposals_controller:
def send_proposal
#proposal = Proposal.find(params[:id])
ProposalMailer.send_proposal_to_client(#proposal, #proposal.request.user).deliver_now
#proposal = #proposal.update_attributes(status: "Sent to Client")
#proposal.request = #proposal.request.update_attributes(archived: "Proposal Sent to Client") <<<<<<<<<ERROR CALLED ON THIS LINE
flash[:notice] = "Your proposal has been sent to the client!"
end
I have looked at many SO posts for other TrueClass errors, but can't seem to find one with a problem like this. Can anyone see what I'm doing wrong or help me conceptualize what TrueClass errors are generally about?
update_attributes is an alias for update:
update(attributes)
Updates the attributes of the model from the passed-in hash and saves the record, all wrapped in a transaction. If the object is invalid, the saving will fail and false will be returned.
and update returns true or false (the documentation could be a lot more explicit about this) not the updated model instance. So this:
#proposal = #proposal.update_attributes(status: "Sent to Client")
will leave #proposal as true or false and neither of those have an update_attributes method.
Your controller method should look more like this:
def send_proposal
#...
#proposal.update(status: "Sent to Client"))
#proposal.request.update(archived: "Proposal Sent to Client")
#...
end
You probably want to do some error checking on those two update calls too.

Rails : Undefined Method in models

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.

How do I handle nil in models properly?

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

Spec Failing undefined method `parameterize'

I have a custom validation on a model and I'm getting undefined method which makes no sense.
Here's the code
validate :unique_seo_url_from_title
def unique_seo_url_from_title
url = "#{title.parameterize}-#{region.parameterize}-#{country}"
errors.add(:title, "already in use") if SeoMapping.find_by_seo_url(url)
end
Strange thing is if I output the url ie raise url it prints it perfectly so its working.
Hope someone can advise!
Since you didn't pass parameters to the function, it seems that title, region and country are attributes of model for which validation is used. So use self for the object
validate :unique_seo_url_from_title
def unique_seo_url_from_title
url = "#{self.title.parameterize}-#{self.region.parameterize}-#{self.country}"
errors.add(:title, "already in use") if SeoMapping.find_by_seo_url(url)
end
Thanks
undefined method `parameterize' for nil:NilClass
The message means exactly what it says. You have an object which is nil, and you call parameterize on it -- which fails because that method is defined on String, not NilClass.
Check that the values for title and region are present. If not, there's your problem.

Resources