Nil can't be coerced into Fixnum Error - ruby-on-rails

So I have a product page and i must create new products. When creating a new product i hit the error referenced in my title question. (nil can't be....)
app/models => `+'
return (((vat_part(discount_percent, date, options) + non_vat_part(discount_percent, date, options))*1.2).round(2)/1.2).round(rounded ? 2 : 1000)
I suppose the plus sign is a major cause of this error.
Anyway, I appreciate any hints and advices.

Try converting nil to 0 (with to_i or to_f, depends on your logic):
return (((vat_part(discount_percent, date, options).to_i + non_vat_part(discount_percent, date, options).to_i)*1.2).round(2)/1.2).round(rounded ? 2 : 1000)

Related

TypeError: no implicit conversion of Fixnum into Hash - Ruby

Did I try google?
Yes, I tried stack overflow, google, rubydocs, bunch of websites but there are minimal results to this and it's only ever mentioned indirectly. So yes, I did a lot of searching.
What's working?
I run the following query:
requests = Request.where("customer_id = ?
AND request_method != ?
AND request_time
BETWEEN ? AND ?",
customer.id, "OPTIONS", start_time, end_time).group('request_time')
As a result I get a bunch of values from the Database which look like this and this is CORRECT:
#<ActiveRecord::Relation[#<Request id: 171792, request_time: "2022-04-04 14:07:20">,
#<Request id: 171787, request_time: "2022-04-04 14:06:02">...]
NOTE: I didn't paste all the values because they have a similar structure.
What's the problem?
After running the query I want to pass it to the variable dates_init_hash = {} and merge it whilst counting into data[:requests]:
dates_init_hash = {}
(start_time.to_date..end_time.to_date).each do |date|
dates_init_hash[date] = 0
end
data[:requests] = dates_init_hash.merge(requests.count)
Unfortunately, I always seem to be getting the error:
ERROR -- : TypeError: no implicit conversion of Fixnum into Hash
Expected
I should be getting a Hash like the following:
{ "2022-03-24"=>2, "2022-03-25"=>1, "2022-03-28"=>3, "2022-03-29"=>11}
What I tried
I tried to convert the results to a hash before passing it over but this gave me the error that the .to_h method doesn't exist
data[:requests] = dates_init_hash.merge({requests: requests.count }) works half-way still causing errors
Questions
Why am I getting a Fixnum and why won't this work? How can I improve this? What would be the right way to solving this? I appreciate any kind of help.
Why is the error happening?
You are getting the error because when you run:
data[:requests] = dates_init_hash.merge(requests.count)
dates_init_hash is a hash, and requests.count is a number. So you are trying to merge a number into a hash, what is not allowed.
How can I fix it?
If what you want is to have the dates_init_hash with a mapping date => number of requests that date, you can do the following:
# initializes dates_init_hash with desired dates
dates_init_hash = {}
(start_time.to_date..end_time.to_date).each do |date|
dates_init_hash[date.iso8601] = 0
end
# iterates over reuests and add 1 to the date in dates_init_hash for each request in the desired date
requests.each do |request|
date = Date.parse(request[:request_time]).iso8601
next if dates_init_hash[date].nil?
dates_init_hash[date] += 1
end
Then, dates_init_hash will be something like
{"2022-04-04"=>1, "2022-04-05"=>0, "2022-04-06"=>1, "2022-04-07"=>0}

Rails routing - optional parameters not working

I have the code below in my routes.rb file:
get 'page/contact_us(/:year(/:month))'=>'page#contact_us', :as => 'contact_us'
The idea is that entering year and month in the url are optional. But whenever I try to go to the address:
localhost:3000/page/contact_us
I get an error. It's only when I enter both a year and a month that I don't get an error. For example,
localhost:3000/page/contact_us/2014/11
works!
Rails tells me that the error is in the contact_us.html.erb file. The error line is:
<%=contact_us(#month,#year).html_safe%>
The contact_us(month, year) function is defined in a helper file - page_helper.rb
The idea is that 2 arguments are usually passed above (in the url), but sometimes 1 or no arguments may be passed in the url. I get an error when less than 2 arguments are passed.
Please help! I'm using rails 4.1.8 and Rubymine
Your invalid date error is coming from the calendar method that you included a link to you in your comments. You have:
def calendar(month, year)
current_date = Date.new(year, month, 1)
...
The problem is that if month or year is nil, you are basically doing this (in this case, assuming both are nil):
current_date = Date.new(nil, nil, 1)
Just run rails console and try that: you get this error - TypeError: no implicit conversion from nil to integer.
So the problem isn't with your url, its before. You could add some lines like this to fix that error:
def calendar(month, year)
month ||= 1
year ||= 1900
current_date = Date.new(year, month, 1)
...
...but then you'll have to keep track of the fact that those aren't correct dates so that they don't get passed in the url, wherever that happens.

undefined method `gsub' for nil:NilClass

I'm newvbie in ruby on rails.. I'm having problem with gsub.. I everytime I go to the list of my store page it says "undefined method `gsub' for nil:NilClass"..
here is mycode :
def self.search(search_val, page = 1)
#search_val = search_val.gsub("'", "\\\\'")
search_query = "store_id LIKE '%#{ #search_val }%' OR english_name LIKE '%#{ #search_val }%' OR chinese_name LIKE '%#{ #search_val }%'"
select("jos_store.id, store_id, english_name, chinese_name, store_manager, delivery_area,year, week").joins("LEFT OUTER JOIN (SELECT id as store_replenishment, store, MAX(stock_movement) AS stock_movement FROM jos_store_replenishment GROUP BY store) AS replenishment ON replenishment.store = jos_store.id").joins("LEFT OUTER JOIN jos_stock_movement ON jos_stock_movement.id = replenishment.stock_movement").where(search_query).order("year DESC, week DESC").paginate :page => page, :per_page => 15
end
thanks in advance
A good practice is doing .to_s when you are using string methods.
You can use the & operator on search_val. It allows you to avoid null pointer exceptions without adding additional checks or using to_s to convert a string to a string.
So, you'll have something like this:
#search_val = search_val&.gsub("'", "\\\\'")
You can read more on the safe navigation operator here: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
This means that search_val is in fact nil. You can easily verify this by printing out the value of search_val.
I'm not sure if this is your case, but the same undefined method gsub for nil:NilClass error happened with me after a few rollbacks and migrations.
Then, I restarted the server and works. Maybe this could be the case for some people that reached this topic searching on Google.

Rails: My code causing "can't convert nil into String"

This code from my developer below... does it expect something like "1 - January" and try to parse it into something else?
I changed the code on my form so now the value being passed to this controller is just "1" instead of "1 - January"
How can I fix this so I don't get the "can't convert nil into string" error?
def get_expiry_month_number(monty_det, expiry_year)
if MONTH_NAMES.include? monty_det
month_number = MONTH_NAMES.index(monty_det)
month_number = MONTH_NUMBERS[month_number]
expiry_year = month_number.to_s + expiry_year[expiry_year.length-3..expiry_year.length-1]
return expiry_year
end
end
In your example you are running into the problem that one of your strings in your calculation for year is nil. Most likely this one,
expiry_year[expiry_year.length-3..expiry_year.length-1]
You can try and fix this by calling to_s on the culprit variable, thus converting the nil into '' and then concatenated.
Like so: expiry_year = month_number.to_s + expiry_year[expiry_year.length-3..expiry_year.length-1].to_s
However, this may have other seen consequences and isn't recommended. A better approach would be to find out why something you expect is a string is turning out to be empty, and perhaps displaying an appropriate error.
Could you explain a little bit more about what the function is supposed to do? And perhaps the value of expiry_year and monty_det when the error occurs? puts statements can be a big help here.
I guess that get_expiry_month_number('january', 2011) would return: 1011.
Indeed:
month_number should return 1 for january
expiry_year[expiry_year.length-3..expiry_year.length-1] returns the 3 last characters of 2011 => 011

How to compare dates?

get_time_now = Time.now.strftime('%d/%m/%y')
question_deadline_time = (question.deadline.to_time - 2.days).strftime('%d/%m/%y')
if get_time_now == question_deadline_time #2 days till deadline
Notifier.deliver_deadline_notification(inquiry, question, user, respondent , i)
end
I need :
If until deadline's date are remaining 2 DAYS so I deliver email. How i can do it?
UPD
when i write:
deadline = question.deadline.midnight - 2.days
if Time.now.midnight >= deadline
I get:
lib/scripts/deadline_notifier.rb:26: undefined method `midnight' for "19/07/11":String (NoMethodError)
from lib/scripts/deadline_notifier.rb:18:in `each'
from lib/scripts/deadline_notifier.rb:18
without midnight i get:
lib/scripts/deadline_notifier.rb:26: undefined method `-' for "19/07/11":String (NoMethodError)
from lib/scripts/deadline_notifier.rb:18:in `each'
from lib/scripts/deadline_notifier.rb:18
Use a combindation of .midnight (or .end_of_day) and 2.days to get what you want:
deadline = question.deadline.midnight - 2.days
if Time.now.midnight >= deadline
#deliver
end
edited:
I highly recommend you change question.deadline to be a datetime. If you can't do that, then you need to convert your string to a date to perform calculations on it. #floor's method works fine, or you can do this as well:
"2011-07-18".to_date
From the error it looks like you are trying to run a DateTime method on a string. If you have a DateTime object and run a strftime('%d/%m/%y') on it, you can't call DateTime methods any more because it is no longer an object, just a plain ol' string. So you can't run midnight or use the subtract operand.
Also, what format is the string that you are storing? You can try casting it with "date string".to_date, then running your methods on it.

Resources