Reputation: 6451
The following breaks if names
is nil
. How can I have this map
execute only if it's not nil
?
self.topics = names.split(",").map do |n|
Topic.where(name: n.strip).first_or_create!
end
Upvotes: 6
Views: 9663
Reputation: 3077
Finally in ruby 2.7 you can use
['Moscow', 'Norilsk'].map do |city|
city if city == 'Norilsk'
end
=> [nil, "Norilsk"]
['Moscow', 'Norilsk'].filter_map do |city|
city if city == 'Norilsk'
end
=> ["Norilsk"]
Upvotes: 0
Reputation: 36110
From ruby 2.3.0 onward, you can use the safe navigation operator (&.
):
self.topics = names&.split(",").map do |n|
Topic.where(name: n.strip).first_or_create!
end
Upvotes: 0
Reputation: 160611
I think the real problem is you're not checking to see if it's safe to perform the action, and then have to scramble to try to recover when it's not safe.
Instead, check to see if names
is valid before you try to split
it. You don't say what self.topics
should be if names
is nil, but I'd start with something like:
self.topics = if names.nil?
# whatever self.topic should be if names == nil
else
names.split(",").map do |n|
Topic.where(name: n.strip).first_or_create!
end
end
Upvotes: 0
Reputation: 38645
A couple of other options:
Option 1 (checking for result of split
when executing map
on it):
names_list = names.try(:split, ",")
self.topics = names_list.map do |n|
Topic.where(name: n.strip).first_or_create!
end if names_list
Option 2 (using try
, which will prevent the error):
self.topics = names.try(:split, ",").try(:map) do |n|
Topic.where(name: n.strip).first_or_create!
end
Upvotes: 8
Reputation: 35531
That depends on what you want topics
to become if names
is actually nil. The most elegant solution would probably be to substitute an empty string where names
is nil:
self.topics = (names || '').split(",").map do |n|
...
But that would assign an empty array to topics
. If that's not what you want, you can wrap this with a nil
check like this:
if names
self.topics = ...
end
Or like this:
self.topics = names.split(",").map do |n|
...
end if names
Upvotes: 1