Error using Ruby OR in if - ruby-on-rails

I have this simple condition in my ruby code:
if user.text != ("Empty" || "Damaged")
do something...
the thing is that when it is "Damaged" it still enters the loop, so I have to use this:
if user.text != "Empty"
if user.text != "Damaged"
...
..
What is the correct syntax to make the first one work?
Thanks!

Use this:
unless ["Empty", "Damaged"].include?(user.text)
...
end
The problem with your first approach is that a || b means that: if a != nil then it is a, else it is b. As you can see it is good for variables, not constants as they are rarely nil. Your expression ("Empty" || "Damaged") simply equals "Empty".
You want to use the this as a binary operator, the correct form would be:
if (user.text != "Empty") && (user.text != "Damaged")
The upper solution is just shorter. It consists of an array of elements you want to avoid, and you just simply check is the user.text is not present in it.

#Matzi has the right answer, for sure. But here's why what you're doing is failing:
Your statement ("Empty" || "Damaged") evaluates to "Empty"
You're saying return either one of these, whichever non-false thing you find first. In Ruby, any string, number or Object returns true, so you return "Empty" every time.
A better way to lay it out if you really want to use an if statement:
if user.text != "Empty" && user.text != "Damaged"
...
end
I assume, by the way, that you're trying to say "If the user text is neither Damaged nor Empty".
Hope that helps.

if ((text != "Empty") && (text != "Damaged"))

Related

Ruby case multiple conditions with and

I've got below case condition which works well.
case params[:event_type]
when 'publish'
StoreActivityWorker.perform_async(params)
when 'delete'
DeleteActivityWorker.perform_async(params)
end
But I want to add another conditions to each when - name == %w[Text Video Audio] so the code should be like:
case params[:event_type]
when 'publish' && name == %w[Text Video Audio]
StoreActivityWorker.perform_async(params)
when 'delete' && name == %w[Text Video Audio]
DeleteActivityWorker.perform_async(params)
end
but it won't work, it shows false every time.
name is just:
params.dig('entity', 'relationships', 'item_type', 'data', 'name')
Currently you're checking if
('publish' && name == %w[Text Video Audio]) === params[:event_type]
or if
('delete' && name == %w[Text Video Audio]) === params[:event_type]
The left side of === can be either true or false and I don't think params[:event_type] is going to be either of those two values, so neither of your two cases are going to be executed.
What you probably want is something like:
if name == %w[Text Video Audio]
case params[:event_type]
when 'publish'
StoreActivityWorker.perform_async(params)
when 'delete'
DeleteActivityWorker.perform_async(params)
end
end
Even that seems a bit off since you're checking if name is equal to %w[Text Video Audio] which I don't think is going to be the case. Perhaps you want:
%w[Text Video Audio].include?(name)
A nested case inside of an if statement is also not the best option. I might suggest a guard clause but without knowing the entire method it's hard to tell.
The expression 'publish' && name == %w[Text Video Audio] does not make sense. Remember that && is a shortcut operator: (E1) && (E2) evaluates E1, and if the result is falsy, returns this value (i.e. nil or false), without even looking at E2. If E1 is trueish, it evaluates and returns E2. In your case, 'publish' is trueish, and hence E2 is returned.
Your E2 is
name == %w[Text Video Audio]
and this expression evaluates to either be true or false, and neither can match your params[:event_type], because the event type is likely not truenor false, but a string, and therefore the condition does not fire.

Append strings if not nil

In the view of a rail's app, I want to achieve:
If user's height isn't nil: return the height value with string "cm"
Otherwise: return string "N/A".
I'm wondering if there's a way to do this. The code below:
user.try(:profile_name).try(:push("as Alias")) || "N/A"
isn't working. The part try(:push("cm")) gives me an error. I thought of using the << operator to append strings by using , but I think there should be a neater way to complete this. Is there anyone who can give me a hint?
--another similar example which I want to accomplish but not working:
user.try(:height).try(:to_s).try(:push("cm")) || "N/A"
How about:
(user && user.profile.present?) ? "#{user.profile} as Alias" : 'N/A'

Need to make this expression shorter in ruby on rails 3

I need to make my code more compact. I have the following code:
params[:investor][:profit] = params[:investor][:profit].nil? ? nil : params[:investor][:profit].gsub(/\D/, '')
Basically what it does - it formats profit value from params to contain only digits, and if it was nil - just keep it nil...Is there any way to make it shorter.
You could tighten it down a little bit like so:
params[:investor][:profit].gsub!(/\D/, '') unless params[:investor][:profit].nil?
You could use the #try method from active_support:
params[:investor][:profit].try(:gsub!, /\D/, '')
um
p = params[:investor][:profit]
p = p.nil? ? nil : p.gsub(/\D/,'')
params[:investor][:profit] &&= params[:investor][:profit].gsub(/\D/, '')
If the value of params[:investor][:profit] is nil, this will evaluate to nil && .... Since nil is false, it will stay at nil, otherwise do the gsub.
I think it is heads up with the try solution mentioned in another solution. Choosing one over the other comes down to personal taste. I like the &&= solution because it's ruby instead of a rails convenience method and you do not need to "encrypt" what you really want to do in the try method's parameters.
params[:investor][:profit].gsub!(/\D/, '') if params[:investor][:profit]
or what I almost always use:
params[:investor][:profit].gsub!(/\D/, '') rescue nil
prof = params[:investor][:profit]
prof.gsub!(/\D/,'') if prof

Firefox scripting language: URL of active Tab and counting open Tabs

Edit: I was able to go one step further :)
PSEUDO CODE (what I want)
if (CurrentTabURL == empty Tab) and (Tab.Count == 1)
{close Firefox}
else
{close Tab}
MY CODE (only the if statements don't work. Both actions are working)
if (gBrowser.currentURI == "")
and (tabbrowser.browsers.length == 1)
then
goQuitApplication();
else
gBrowser.removeTab(gBrowser.mCurrentTab);
end
This link helped me a lot.
gBrowser.currentURI is an nsIURI instance. If you want to compare the URL to a string you should look at gBrowser.currentURI.spec. The URL of an "empty tab" is about:blank by the way. Also, I guess that you want to use JavaScript? Corrected code:
if (gBrowser.currentURI.spec == "about:blank" && gBrowser.browsers.length == 1)
goQuitApplication();
else
gBrowser.removeTab(gBrowser.selectedTab);

ruby: how avoid if-then-else when doing case-insensitive comparison that handles nil too

I frequently find myself having to do an extra nil check (to avoid throwing an 'undefined for nil' error) that I'm pretty sure is unnecessary.
In one common example, when looking at optional url params, e.g. which might or might not exist, I like them to be case insensitive (if they exist).
for example one of my controller methods allows (doesn't require) &showdate=true and I like to make it user friendly by not caring about true vs TRUE vs True.
I could just say
#showdate = params[:showdate] == "true"
but that assumes lower case.
If I do this:
#showdate = params[:showdate].lower == "true"
it of course throws an unwanted error if showdate is missing from the url becasue nil.lower throws an error.
So I end up doing something like this LOTS of time in my code:
if params[:showdate]
#showdate = params[:showdate].lower == "true"
else
#showdate = false (or maybe nil)
I know there's a Better Way, just don't know what it is. Any help would be appreciated.
#showdate = params[:showdate].to_s.downcase == "true"
Rails?
#showdate = params[:showdate].try(:downcase) == "true"
or
#showdate = !!params[:showdate] && params[:showdate].downcase == "true"
You could do it this way:
#showdata = (params[:showdate] || '').downcase == 'true'

Resources