Dealing with expected nils - ruby-on-rails

I expect to see a nil returned with the following embedded Ruby:
<%=h [#inventory.origin.code] %>
it returns a "NoMethodError nil object". However when an object is in fact present, it functions just fine (as expected).
Therefore I created this test (following this advice):
<b>origin_id:</b>
<% if (#inventory.origin.code.nil? or #inventory.origin.code == 0) %>
<%=h [#inventory.origin] %>
<% else %>
<%=h #inventory.origin.code %>
<% end %>
unexpectedly rails returns NoMethodError "You have a nil object when you didn't expect it!"
Do you have any suggestions in dealing with this situation? Thanks!

You are adding the .nil? check too late. I am assuming it is origin that is nil, not code or you wouldn't be getting that error. Use this instead:
<%=h [#inventory.origin.code] unless #inventory.origin.nil? %>

Refactor of dcneiner's answer:
<%=h [#inventory.origin.code] if #inventory.origin %>

Related

Rails for Date format issue

I am trying to output just the date on the generated line, but when I execute this code, which I am sure is not elegant at all, it gives me undefined method 'strftime' for nil:NilClass
<% #person.subordinates.each do |sub| %>
<tr>
<td>
<% if sub.position == 'alumni' %>
<p>
<%= link_to(sekret_person_path(sub.position, sub.user_name)) do %>
<strong><%= sub.fname %> <%= sub.lname %>,</strong>
<% end %> <%= sub.startdate.strftime("%Y") %> - <%= sub.graddate.strftime("%Y") %>
</p>
<% end %>
</td>
</tr>
<% end %>
Further up in my code, I am using #person.startdate.strftime("%m/%d/%Y") without any issue, but I think my issue is that I am using the sub call, which is grabbing any people that are flagged as sub to this person.
Your error says that one of your attributes is nil. The sytax is correct. Try debugging with:
#person.subordinates.select { |sub| sub.startdate.nil? || sub.graddate.nil? }
The elements that are retrieved on this line will be the ones that are giving you errors, because you are trying to run nil.strftime('%Y'), which makes sense.
You should use a condition on your .erb to stop it, like:
<%= sub.startdate && sub.startdate.strftime("%Y") %> - <%= sub.graddate && sub.graddate.strftime("%Y") %>
It is not an error with Rails.
strftime is being called on nil object. Make sure you are calling strftime on a date, time, or datetime object.
Refer to strftime on rails apidock - https://apidock.com/ruby/DateTime/strftime
Another way to solve this that will guard against nils would be:
<%= sub.startdate&.strftime("%Y") %> - <%= sub.graddate&.strftime("%Y") %>
That way you don't have to add a conditional to make sure that any method/attribute in the chain exists prior to calling them. This works because of the safe navigation operator, which is explained in depth here: https://rubyinrails.com/2017/11/17/safe-navigation-operator-ampersand-dot-in-ruby/

Ruby on Rails: Getting Value From Relationship

I have a loop to getting values in my database, but when I'm trying to get a value from a relationship, I get an error:
undefined method `first_name' for nil:NilClass
This is the loop:
<%= #sample.each do |s| %>
<%= s.relation.first_name %>
<% end %>
when I tried
<%= s.relation.to_json %>
with .to_json, I get this:
{"first_name":"testingtwo","last_name":"fdsaf","updated_at":"2013-11-21T07:47:05Z","user_id":null}
Shouldn't s.relation.first_name work?
Thanks
it's possible that there is a relation in the loop that doesn't have a value, and is getting hung up there - try this:
<%= #sample.each do |s| %>
<%= s.relation.first_name if s.relation %>
<% end %>
this only outputs s.relation.first_name if it isn't nil. You could also try this:
<%= #sample.each do |s| %>
<%= s.relation.first_name || "No name given" %>
<% end %>
which puts the first name if it exists, or "No name given" if it doesn't
One important thing you may want to consider too is whether or not having nil values within your database for that particular relationship is valid to begin with.
The || solution proposed is definitely a good one and a great Ruby pattern, but it may be worth adding in an ActiveRecord validation to ensure your relation(ships) are never nil.
ActiveRecord Validations are definitely the way to go in that particular case.

Why am I getting an undefined method error in rails after I check if method exists?

On my user profile page in my rails app, I am recieving the error:
undefined method `title' for nil:NilClass
I know it is because of the following 3 lines of code:
<% if #user.profile.title %>
<%= #user.profile.title %>
<% end %>
I don't understand why. Since i use the if statement, shouldn't it first check whether title exists, then if it exists display it, and if it does not exist, it should not display it. What is wrong and how do I fix it? Thanks.
Since title is nil you can't test against it like you did.
Try:
<% if #user.profile.try(:title) #user.profile.title %>
You can do:
<% if #user.profile.present? %>
<%= #user.profile.title %>
<% end %>
Or with try:
<%= #user.profile.try(:name) %>
With a default value if no profile associated:
<%= #user.profile.try(:name) || 'No profile for this user' %>
Because it is not correctly. If you want to get access to some parameter from user you have to use direct access. But if you want to use profile that belongs to User model look at this
link

How do I check if a string is equal to another string?

In my rails app, I'm trying to check if one string (current_user.email) is equal to another string, (#user.email).
How would I do this with an if/else statement?
I tried
<% if #current_user.email(=#user.bio) %>
Link
<% else %>
<% end %>
but I got a syntax error. help?
The invalid syntax is (=#. The = is for assignment and has no use in method invocation.
Your if line should look like
<% if #current_user.email == #user.email %>
<% if #current_user.email == #user.bio %> try this & see.

simple rails code optimisation

<% if defined?(#club.name) && !(#club.name).nil? %>
<%= #club.name %>
<% else %>
clubs:
<% end %>
first line looks ugly. any help is appreciated.
Perhaps:
<% if #club && #club.name %>
<%= #club.name %>
<% else %>
clubs:
<% end %>
Since #club will presumably either be set to a Club object or be set to nil, we don't really need to explicitly check whether or not the #club has a name method. Instead, we can just test that #club is set at all, and a truthiness test will suffice for that.
Similarly, we don't need an explicit nil check on #club.name. All values other than false and nil are considered "truthy," and, since a club's name presumably can't be set to false, simply testing its truthiness is equivalent to explicitly checking if it is nil.
Violet pointed out in the comments that this is actually a fairly common idiom in the Rails world, so a shortcut actually exists. In a Rails environment, all objects, including nil, have a method named try. try invokes the method name passed to it as an argument, and either returns that method's return value, or nil if that method is not defined.
So, for example:
no_name = Club.new
no_name.try(:name) # => nil
so = Club.new :name => 'StackOverflow'
so.try(:name) # => "StackOverflow"
nil.try(:name) # => nil
As such, the following is the exact equivalent to the first code block:
<% if #club.try(:name) %>
<%= #club.name %>
<% else %>
clubs:
<% end %>
Much prettier :)
<%= #club.name || "clubs:" %>
how about that?

Resources