Undefined method `assessment' for nil:NilClass - ruby-on-rails

I'm getting this following error:
undefined method `assessment' for nil:NilClass
My code below has the conditional unless to exclude if the method is nil, but is not working. I have also tried the if conditional as well, but not no avail.
I think I need to default to a number if assessment is nil, but unsure on how to do that.
The date is formatted in milliseconds: 1482985235000
<% #sales.methods.each do |data| %>
<%= Time.at(data.assessment.assessment_date/1000).strftime("%d/%m/%Y") unless data.assessment.assessment_date.nil? %>
<% end %>

Try using safe navigation operator or have a chain of try.
data.try(:assessment).try(:assessment_date).nil?.
Or by using safe navigation operator.
data&.assessment&.assessment_date.nil?.
This error is generated when any method is called on nil. If data is nil then assessment will generate error if assessment is nil then assessment_date will. Either way you need to make sure both are present.
We generally don't use inline rescue and handle this type of scenarios by checking both objects. You can go with any of option or you can also check data.assessment.present? && data.assessment.assessment_date.present?

The error says that you are calling the method assessment on a nil... this means that the thing that is nil is data. Your conditional is checking whether data.assessment.assessment_date is nil... but it won't even get to the check for whether assessment_date is nil because it's already failing at data.assessment

I have found a solution to the problem. Not sure if it's the best method, but it works. I added rescue 0 to the end of the call.
<% #sales.methods.each do |data| %>
<%= Time.at(data.assessment.assessment_date/1000).strftime("%d/%m/%Y") rescue 0 %>
<% end %>

Related

If, else dynamic statement logic

Can someone explain the logic behind this code?(This is the correct code btw)
<% if #request.query['first_name'] && !#request.query['first_name'].empty? %>
Welcome! <%= #request.query['first_name'] %>
<% else %>
Hi! What is your name?
<% end %>
My intuition is to write the following instead:
<% if #request.query.inspect['first_name'].empty? %>
Hi! What is your name?
<% else %>
Welcome! <%= #request.query.inspect['first_name'] %>
<% end %>
I am trying to have a user form where people can input their names, when there is no input yet the text above the form says "Hi! What is your name?" when there is an input it has a message saying "Welcome! *User_name*"
The first block of code is not intuitive to me, the second one would make more sense.. ANy advice on how to understand the code?
Your intuition is correct, though you need an alternative to empty?. Rails adds a few different methods you can use:
blank? returns true if the receiver is nil, an empty array, string, or hash, or a string with only whitespace.
present? returns true if blank? is false. So your condition could be:
<% if #request.query['first_name'].present? %>
Welcome...
(I find it's always more intuitive to start with the positive condition - it would work just as well to check blank?).
Edit: It's pretty likely you can skip the query method entirely if all you expect there is either a string or nil. Just use:
<% if #request.query['first_name'] %>
You need to check if it's nil before you can check if its empty, because you are checking a Hash#empty?
irb(main):001:0> nil.empty?
NoMethodError: undefined method `empty?' for nil:NilClass
from (irb):1
irb(main):002:0> {}.empty?
=> true
The code checks for hash key existence, then check if the value of the hash is present. This action can be done in one check using:
#request.query.try(:[], 'first_name').empty?
You can avoid the first condition inside the if statement by transforimng nil into an empty string. I don't know if that is what you meant to do but you almost had.
First, you shouldn't call inspect in the hash because it will transform the entire thing into a 'complex' string. What you want to do turn only the value inside the first_name option, because in that case if the name exists it will still be the same, and if it doesn't, it will be turned into "nil".
Secondly, the method inspect isn't the best choice here, because the returned string will never be empty, given that nil.inspect => "nil". What you should use is the method to_s, wich will behave like this when applied to nil: nil.to_s => "".
Finally, you could update your code to:
<% if #request.query['first_name'].to_s.empty? %>
Hi! What is your name?
<% else %>
Welcome! <%= #request.query['first_name'] %>
<% end %>

Ruby on Rails: Trying to understand Undefined method, nil:NilClass

I'm trying to understand how I'm getting two different outputs from rails
If I have this:
<%= if value.user.present?
link_to value.user.email, value.user
end %>
I gives me what I wanted. It out puts the email of the user with its link associated with it.
But when I take the if statement out,
<%= link_to value.user.email, value.user %>
I get this error.
undefined method `email' for nil:NilClass
I don't get it? Aren't I just doing the same thing with the first statement? It outputs the link_to.
Why am I get two different outputs with what I thought was the same statement?
That's happening because you called a method on nil (value.user is nil)
An easy way to shorten it up...
<%= link_to(value.user.email, value.user) if value.user %>
A note, if value.user could be nil (not false), but is still considered 'falsey' in ruby.
in your if condition it checks whether your user is present and if present it will give the proper output... but somehow if your user is not present it will check like for nil and generates that error, to avoid that you have to write the condition or rescue nil on that line...
This error would pop up if any of your value.user items do not have an email associated.
I've encountered this when migrating and not all rows have the item assigned.

Count Method on Undefined Active Record Array #objects.count

Is there a way to write a clean if nil then in a view. Assuming my lack of ruby is biting me here. Example,
If object nil, then return, nothing found
have
<%= #objects.count if #objects %>
want something like this
<%= #objects.count if #objects then "nothing found" %>
There are many ways to write something like this.
Something simple would be:
<% if #objects %>
<%= #objects.count %>
<% else %>
nothing found
<% end %>
If you get into a slightly more complex conditional I would suggest moving the logic into a helper and call it from the view. ex:
<%= count_for(#object) %>
Here's a good solution for you:
<%= "nothing found" unless #objects.try(:length).to_i > 0 %>
One of the issues is that you can't run count on a nil object. Therefore you need to use Rails' super handy .try() method to return nil when #objects = nil, rather than NoMethodError.
Next issue: You can't make a comparison between nil and a number using > so you need to convert the results of #objects.length to an integer which will return 0 for nil.
Lastly, try calling length rather than count. This will avoid running any extra queries when #objects is defined.
Avoids: SELECT COUNT(*) FROM 'objects'
Also if you want to display the count using this one-liner technique you can simply write up a shorthand if/else statement as follows:
<%= #objects.try(:length).to_i > 0 ? #objects.length : "nothing found" %>
One last option:
Use the pluralize method, which can handle a nil count:
Showing <%= pluralize( #objects.try(:length), 'object' ) %>
Sorry, I know this is pretty late, but hopefully helpful for someone else!

Dealing with nil in views (ie nil author in #post.author.name)

I want to show a post author's name; <% #post.author.name %> works unless author is nil. So I either use unless #post.author.nil? or add a author_name method that checks for nil as in <% #post.author_name %>. The latter I try to avoid.
The problem is that I may need to add/remove words depending on whether there is a value or not. For instance, "Posted on 1/2/3 by " would be the content if I simply display nil. I need to remove the " by " if author is nil.
Null object pattern is one way to avoid this. In your class:
def author
super || build_author
end
This way you will get an empty author no matter what. However, since you don't actually want to have an empty object sometimes when you do expect nil, you can use presenter of some kind.
class PostPresenter
def initialize(post)
#post = post
end
def post_author
(#post.author && #post.author.name) || 'Anonymous'
end
end
Another way is using try, as in #post.author.try(:name), if you can get used to that.
You can use try:
<%= #post.author.try(:name) %>
It will attempt to call the name method on #post.author if it is non-nil. Otherwise it will return nil, and no exception will be raised.
Answer to your second question: In principle there is nothing wrong with the following:
<% if #post.author %>
written by <%= #post.author.name %>
<% end %>
or
<%= "written by #{#post.author.name}" if #post.author %>
But if this is a recurring pattern, you might want to write a helper method for it.
# app/helpers/authors_helper.rb or app/helpers/people_helper.rb
class AuthorsHelper
def written_by(author)
"written by #{author.name}" if author
end
end
# in your views
<%= written_by(#post.author) %>
Write a method which accepts any variable and checks to see if it is nuil first, and if it is not displays it. Then you only have to write one method.
I found your question interesting as I have often come across similar situations, so I thought I'd try out making my first Rails plugin.
I'm afraid I haven't put in any tests yet but you can try it out http://github.com/reubenmallaby/acts_as_nothing (I'm using Ruby 1.9.1 so let me know if you get any problems in the comments or on Github!)

How to check if an object is nil in a view in Ruby?

I would like to display a line of text only if an object called #foo is set.
In my view, I'm trying something like this:
<% if !#foo.new_record? || !#foo.nil? %>
Foo is not a new record or nil
<% end %>
But this fails, returning You have a nil object when you didn't expect it!
I'm pretty sure this happens because of the new_record? method.
How do I check if something is not a new record or nil without causing an error?
In PHP, it would be achieved by asking if(!empty($foo)) but even the empty? method in rails causes the same error to be returned.
Any ideas?
How about:
<% if !#foo.nil? && !#foo.new_record? %>
Hello!
<% end %>
First off, you need to be using AND logic rather than OR logic here, since any ActiveRecord object meets at least one the requirements of "not nil" or "not a new record".
Second, checking for nil first ensures that the second check isn't run if the first one fails. The error is thrown because you can't use #new_record? on an object that doesn't support it, so checking for nil first ensures that that method is never run on a nil.
Let me throw another answer just for fun.
unless #foo.nil? or #foo.new_record?
"Hello"
end
You might be interested in these as well:
<%= #foo.text if #foo.present? %>
or
<%= #foo.text unless #foo.blank? %>
I would check by if #foo && #foo.id. This checks that there is a #foo activerecord object and makes sure the id field is not empty. If the id field is empty, that means it's not a record in the database yet. I assume you are using id field in the table.
The simple way is
<% if !#foo.try(:new_record) %>
Hello!
<% end %>
Is there a reason why this object might be nil when it gets to the view? Sometimes adding conditional logic like this in the view can be a sign that something could be refactored and you are just masking a bigger problem.
I much prefer to use the andand gem for these checks.
if #foo.andand.id
"Hello!"
end
The call to .id will only be made on non-nil objects.

Resources