Can't convert nil to string -- edited to restate all the failing attempts
Solution 1
The test current_part.to_s == ""
returns true
on my ruby system when current_part
is nil
. Unlike some other languages, you can say nil.to_s
and nil.nil?
and have them work. I think there is something else that is causing the problem. Can you show more of the code?
(My tests were in ruby 1.8.6)
Edit: Looking around, what usually causes the above error is an expression such as "text" + nil
, not nil.to_s
. Do you have anything like that around?
Solution 2
The problem is in your truncated line where concept.title meets the plus.
When you do
"Foo" + some_obj.some_attr
and some_attr in the object is nil, Ruby won't autocast it to string. Might happen often (!) since Rails casts NULL value in the DB to nils. Workarounds are in-string evaluation:
"Foo #{some_obj.attr_that_can_be_nil}"
pattern substitution (automatically truncates nil)
"Foo %s" % some_obj.attr_that_can_be_nil
or array joining (idem ditto)
["Foo ", some_obj.attr_that_can_be_nil].join
The reason you could not find it is that your "truncated line" deserves it's own 5-6 lines unwrapped properly, that way it would be much easier for you to spot the problem.
On a sidenote, you don't need “ and friends - just type it literally since Rails is UTF-8 nowadays anyway. Moreover, when passing stuff to tag helpers you might get this thing converted to “ which is totally not what you want (if helpers escape entities - I don't remember if they do, but Builder certainly does).
steven_noble
Updated on June 05, 2022Comments
-
steven_noble almost 2 years
At a point in my code, I expect
current_part
to sometimes benil
, and I want to run some code (inside anif
block) when that's not the case.Using
script/server --debugger
, I've established thatcurrent_part
is in factnil
at that point when the following errors occur.All the following versions generate the
can't convert nil into String
error on the second line:#
def map_concepts_to_part(part, current_part) if current_part part.concepts.map { |concept| content_tag(:li, "stuff...")}.join end end
#
def map_concepts_to_part(part, current_part) if test_if_exists(current_part) part.concepts.map { |concept| content_tag(:li, "stuff...")}.join end end def test_if_exists(test_subject) test_subject rescue nil end
#
def map_concepts_to_part(part, current_part) if test_if_complete(current_part) part.concepts.map { |concept| content_tag(:li, "stuff...")}.join end end def test_if_complete(test_subject) test_subject.id rescue nil end
#
def test_if_complete(part, current_part) unless current_part.to_s == "" part.concepts.map { |concept| content_tag(:li, "stuff...")}.join end end
#
def test_if_complete(part, current_part) unless current_part.nil? part.concepts.map { |concept| content_tag(:li, "stuff...")}.join end end
#
PS, the truncated line in each of the above is:
part.concepts.map { |concept| content_tag(:li, "Concept: “" + concept.title + "”", :class => "one_concept") + content_tag(:li, "Attached images (" + concept.images.size.to_s + ")", :class => "all_images") + content_tag(:li, "Attached docs (XX)", :class => "all_docs")}.join