Reputation: 5411
I'm trying to comparte two dates in my controller here is the code
if @user.payment.count == 0
some action
elsif @user.payment.last.active_until.to_date > Time.now.to_date
some action
elsif @user.payment.last.active_until.nil?
some action
end
When I try to evaluate this
elsif @user.payment.last.active_until.to_date > Time.now.to_date
I get this error:
undefined method `>' for nil:NilClass
But I have the same line in a view to show some other information and it works great.
I don't understand why in the controller doesn't work.
Thanks in advance for your help.
UPDATE
here is my console output
1.9.3p286 :002 > u.payment.last.active_until
Payment Load (0.2ms) SELECT "payments".* FROM "payments" WHERE "payments"."user_id" = 10 ORDER BY "payments"."id" DESC LIMIT 1
=> Thu, 24 Jan 2013
If I compare this in my console I get this:
1.9.3p286 :003 > u.payment.last.active_until.to_date > Time.now.to_date
Payment Load (0.3ms) SELECT "payments".* FROM "payments" WHERE "payments"."user_id" = 10 ORDER BY "payments"."id" DESC LIMIT 1
=> true
UPDATE 2
the same if in my controller is true and in console is false, I thinks here is the problem
1.9.3p286 :010 > u.payment.last.active_until.nil?
Payment Load (0.3ms) SELECT "payments".* FROM "payments" WHERE "payments"."user_id" = 10 ORDER BY "payments"."id" DESC LIMIT 1
=> false
Upvotes: 0
Views: 1457
Reputation: 15056
The only way that to_date
will return nil
is when you have a blank string. All other strings will raise an exception of some sort. You need to check for a blank string instead of nil?
because "".nil? == false
. Instead, use @user.payment.last.active_until.blank?
. That will check for blank strings and nil.
if @user.payment.count == 0
some action
elsif @user.payment.last.active_until.blank?
some action
elsif @user.payment.last.active_until.to_date > Time.now.to_date
some action
end
Besides that, is there any good reason that you're storing dates as strings?
Upvotes: 0
Reputation: 183
Check your syntax in your model, including validations. All answers I've seen online concerning this type of error are just syntax errors. This error is essentially saying you're trying to call a comparison on the left-hand object, which happens to be nonexistent, so it's probably a problem with your model or validations.
Upvotes: 0
Reputation: 19789
Your problem is with @user.payment.last.active_until
You should do the check for nil
before you try to access that field and you'll probably see that it's empty
A good habit I've created is that every time I access a chain method like that I check along the way if the value is not nil
so I don't unexpectedly call methods on nil
stuff unless I'm absolutely 100% sure that value can never be nil.
payments = @user.payment
if payments.count == 0
some action
elsif payments.last.active_until.nil?
some action
elsif payments.last.active_until.to_date > Time.now.to_date
some action
end
or if you want to keep the same code you had then
if payments.count == 0
some action
elsif !payments.last.active_until.nil? && payments.last.active_until.to_date > Time.now.to_date
some action
elsif payments.last.active_until.nil?
some action
end
Upvotes: 0
Reputation: 42903
Just reorder your statements, so the date is first checked for nil?
:
if @user.payment.count == 0
some action
elsif @user.payment.last.active_until.nil?
some action
elsif @user.payment.last.active_until.to_date > Time.now.to_date
some action
end
PS: Additionally, check that the to_date
method doesn't return nil
for non-nil
objects.
Upvotes: 2