Hello Devs I'm trying to compare dates in a custom validator, but it seems that i'm not doing it properly.
i need to make a condition for a document, if 90 days have passed since the date of expiration, if its true then return an error.
class CheckDocumentValidator < ActiveModel::Validator
def validate(record)
expiration_date = record.expiration_date
actual_date = Time.current
diff = ((actual_date - expiration_date.to_time)/3600).round
days_diff = diff/24
if days_diff > 90
record.errors.add(:expiration_date, "error")
end
end
end
expiration_date is a date attribute on my model AttachmentInstance
In the logs says that -- Error: undefined method `to_time' for nil:NilClass
i think the error
Error: undefined method `to_time' for nil:NilClass
is because no data found on record.expiration_date.
if record.expiration_date is Time class. it should be like this
if record.expiration_date + 90.day > Time.now
record.errors.add(:expiration_date, "error")
end
Related
I'm adding a custom validation in my application while creating a coupon, start date of the validity for the coupon should be before the end date.
validate :to_must_be_after_from
private
def to_must_be_after_from
if valid_to < valid_from
self.errors[:base] << "Coupon cannot expire before the start of its validity period."
end
end
valid_to and valid_from are the date fields.
When I'm running this, NoMethodError occurred. I have the following question regarding this,
'<' is an operator and not a function, then how such error can occurs.
How to fix this and make the code function properly.
Most operators are actually methods in Ruby. This code:
valid_to < valid_from
is merely syntactic sugar to
valid_to.<(valid_from)
The error message is pretty much self explanatory, you have to make sure valid_to and valid_from are not nil, using guard clause, for example, i.e. like this:
def to_must_be_after_from
return if valid_to.blank? || valid_from.blank?
# rest of the code
end
First you need to check whether valid from or valid to is blank or not. then you can check the value is less than or greater than .
def to_must_be_after_from
return if valid_from.blank? || valid_to.blank?
if valid_from < Date.today
errors.add(:base, "You can't select past dates in valid from")
elsif valid_to < valid_from
errors.add(:base, "valid to can't be before the valid from date")
end
end
Based on the error message-
You are trying to compare variables in which one variable is nil.
Can you check if both valid_to and valid_from are having proper values, before checking the validation - if valid_to < valid_from ?
I am creating a chart based on account balance. And here is my some of my codes
module AccountsHelper
def products_chart_data
orders_by_day = Account.total_grouped_by_day(3.days.ago)
(3.days.ago.to_date..Date.today).map do |date|
{
created_at: date,
balance: orders_by_day[date].first.try(:total_balance) || 0
}
end
end
end
class Account < ActiveRecord::Base
belongs_to :user
has_many :books
def self.total_grouped_by_day(start)
balances = where(created_at: start.beginning_of_day..Time.zone.now)
balances = balances.group("date(created_at)")
balances = balances.select("created_at, balance as total_balance")
balances.group_by {|o| o.created_at.to_date }
end
end
My problems are:
1) I received an error undefined method `first' when mapping 3.days.ago, but successfully run the code when I change it to 2.days.ago. I understand that it is because I do not have data on 3 days ago as this account is new. My question is, how can I rescue this error, because I could have many other new accounts that do not have data yet, and what could I do to display result for 1 month, or 2 month?
Thanks in advance!
# ⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓⇓
balance: orders_by_day[date].try(:first).try(:total_balance) || 0
try is the method, introduced by rails and defined on Object class, therefore it is defined on NilClass as well.
The implementation is quite straightforward: it checks whether receiver is empty and returns either the result of the call to it, or nil otherwise.
Trying to reset password I get an error NoMethodError Undefined method `+' for NilClass. I guess it may be due to a devise method
def confirmation_period_expired?
self.class.confirm_within && (Time.now > self.confirmation_sent_at + self.class.confirm_within )
end
because confirmation_sent_at still nil in db. I wonder why
def generate_confirmation_token
self.confirmation_token = self.class.confirmation_token
self.confirmation_sent_at = Time.now.utc
end
doesn't set confirmation_sent_at. No idea why, but generate_confirmation_token isn't called. Any thoughts?
Probably you got the error
def confirmation_period_expired?
total_sent_at = (self.confirmation_sent_at.nil? || self.class.confirm_within.nil?) ? 0.0 : (self.confirmation_sent_at + self.class.confirm_within)
self.class.confirm_within && (Time.now > total_sent_at )
end
you can also use try
Try
def generate_confirmation_token
self.confirmation_token = self.class.confirmation_token
self.confirmation_sent_at = Time.now.utc
# you dont save your instance
save
# now saved
end
It was due the old version of Devise. In previous Devise versions (< 3.1.0), resetting the password automatically confirmed user accounts without sending confirmation. More here http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/
I have two methods which are used to determine whether to apply a class to the page to show that something is overdue and needs attention.
I'm getting an error when a brand new user registers:
undefined method `last_contact_done_date=' for #<User:0x6183708>
The line that it's referencing the error to is this:
2: <div class="span3 <%= "overdue" if (signed_in? && contact_overdue?(current_user.id)) %>">
The contact_overdue? method is this (in a home page helper)
def contact_overdue?(user_id)
#user = User.find_by_id(user_id)
return true if (Date.today - (#user.last_contact_done_date ||= Date.tomorrow)) > 6
end
and the last_contact_done_date method is this in the User model
def last_contact_done_date
self.contacts.order('date_done DESC').first.try(:date_done)
end
I thought that if I was using the ||= operator in the contact_overdue? method, then I would return -1 if the last_contact_done_date is nil. But it appears that's not working. What operator should I be using in last_contact_done_date or how should I change the contact_overdue? method so that if there are no contacts, then false is returned from the contact_overdue? method?
To return the default value of -1 when there is no last contact done date, use
#user.last_contact_done_date || -1
(it is unreasonable to expect Date.tomorrow to return -1 ;) )
||= is an assignment operator; a ||= b is equivalent to a = a || b; and if a is an attribute (i.e. is prefixed with a dot and an instance, c.a), assignment to it will call the method a=. Thus, your code necessitates that you have a method named last_contact_done_date= to handle the assignment, which you don't.
I am getting this error: undefined method `stringify_keys' for :environ_gross_score:Symbol
when I attempt to create a new rating.
class Rating < ActiveRecord::Base
belongs_to :city
after_save :calculate_rating
def calculate_rating
#env = self.environ
self.city.environ_vote_count += 1
#c = self.city.environ_gross_score
#gross = #c += #env
self.city.update_attributes(:environ_gross_score, #gross )
#hold = self.city.environ_gross_score / self.city.environ_vote_count
self.city.update_attributes(:environ_rating, #hold)
end
end
update_attributes takes a single hash, not 2 parameters. Change the line to:
self.city.update_attributes(:environ_gross_score => #gross)
The error was happening because the method assumed that the first argument passed was a hash, which does (in Rails) respond to stringify_keys.