Rails routing - optional parameters not working - ruby-on-rails

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.

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}

Nil can't be coerced into Fixnum Error

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)

Converting a string into a date Ruby on Rails

I'm attempting to convert a string date into a date that can be stored in the database. These are my attempts:
params[:event][:start_date] = '03-21-2016'
DateTime.strptime(params[:event][:start_date], '%Y-%m-%dT%H:%M:%S%z')
or
DateTime.strptime(params[:event][:start_date], '%m-%d-%Y')
However I keep getting an invalid date error. I'm not sure what I'm doing wrong.
One way to do it would be this:
date_string = '03-21-2016'
month, day, year = date_string.split('-').map(&:to_i)
DateTime.new(year, month, day)
You need to understand what each fragment (eg %Y) in the format string ('%Y-%m-%dT%H:%M:%S%z') means: read this.
http://apidock.com/rails/ActiveSupport/TimeWithZone/strftime
Once you know this, you can tailor a format string to the date string you have, or expect to get: in this case, "%m-%d-%Y".
When debugging create a new, basic and simple, version of the code and test that.
require 'date'
params = '03-21-2016'
DateTime.strptime(params, '%m-%d-%Y') # => #<DateTime: 2016-03-21T00:00:00+00:00 ((2457469j,0s,0n),+0s,2299161j)>
Note the order for the format: '%m-%d-%Y', which works. That's the problem with your first attempt, where you tried to use%Y-%m-%d. There is NO month21or day2016`.
Your second attempt is valid but your question makes it appear it doesn't work. You need to be more careful with your testing:
params = {event:{start_date:'03-21-2016'}}
DateTime.strptime(params[:event][:start_date], '%m-%d-%Y') # => #<DateTime: 2016-03-21T00:00:00+00:00 ((2457469j,0s,0n),+0s,2299161j)>

Ruby on Rails: invalid argument to TimeZone[]: nil

NOTE: This is my first post, so please be kind. I'm a rails newb so it's very plausible that i'm missing something simple.
I'm working with a Ruby on Rails application locally and am getting this ArgumentError when attempting to fill out a test form:
invalid argument to TimeZone[]: nil
Application Trace shows the following:
app/models/venue.rb:117:in `timezone'
app/controllers/events_controller.rb:80:in `block in create'
Lines 116-118 in venue.rb:
def timezone
ActiveSupport::TimeZone.new(timezone_name)
end
Lines 78-87 in events_controller.rb:
["start", "end"].each do |t|
month, day, year = params["event"]["#{ t }_date"].split("/")
#event.send("#{ t }s_at=", #event.venue.timezone.local_to_utc(Time.utc(
("20" + year).to_i,
month.to_i,
day.to_i,
military_hours(t),
params["#{ t }_minute"].to_i,
0
)))
The form works correctly on the live site, so its possible that i setup my dev environment improperly. Can anyone point me in the right direction?
UPDATE
class Venue
key :timezone_name, String
def set_timezone_name
tz = Timezone.contains(self)
self.timezone_name = tz.name if tz
end
It would help if you provided more context for this question. I'll assume that set_timezone_name is called to initialize the timezone_name value when there is none set. It's then likely in this case set_timezone_name fails to set a value. You could try providing a fallback to guarantee a value is set. Example:
def set_timezone_name
tz = Timezone.contains(self)
self.timezone_name = tz.try(:name) || “Eastern Time (US & Canada)”
end

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