I am looking for a method (preferably just one Rails or Ruby method) that will validate if a variable is blank but is not false (since I have some boolean variables that should not be blank? == true since they have values).
Say I have four types: nil, '', 0, false.
I am looking for a simple method that is equivalent of the following:
(var.nil? || var == '') && var !== false
This is the simplest I can come up with:
var.blank? && var !== false
If there's no other way, then I guess I'll just have to create a custom-method for this.
I am looking for a simple method that is equivalent of the following:
var.nil? or var == '' or var == false
The method you're looking for is blank?
def foo1(var)
var.nil? || var == '' || var == false
end
def foo2(var)
var.blank?
end
foo1(nil) == foo2(nil) # => true
foo1('') == foo2('') # => true
foo1(false) == foo2(false) # => true
foo1(0) == foo2(0) # => true
After edit
I am looking for a simple method that is equivalent of the following:
(var.nil? || var == '') && var !== false
Yeah, just make a custom method. Or, if you're feeling particularly evil, you can patch FalseClass#blank? to return the opposite value.
Now that your question became understandable, I shall answer.
(var.nil? || var == '') && var !== false
can be simplified to:
var.to_s.empty?
You cannot do it in a single method, but you can do it in two. It will also return true for [], {}, for example.
Related
what I want to query is somethinkg like
Model.where(condition: params[:condition]) if params[:condition] exists.
otherwise its okay to return all.
I came up with one liner like Model.where(condition: params[:condition] || 0..Float::INFINITY)
but it didn't work.
Model.where(condition: 0..Float::INFINITY) works as I expected, so I thought above also would work.
Do you guys have any good idea to query by oneliner? I know ternary operator should work.
params[:condition] || (0..Float::INFINITY) will only return (0..Float::INFINITY) in the case that params[:condition] is nil or false:
{ condition: "" }[:condition] || (0..Float::INFINITY)
# => ""
{ condition: false }[:condition] || (0..Float::INFINITY)
# => 0..Infinity
{ condition: nil }[:condition] || (0..Float::INFINITY)
# => 0..Infinity
You could use Object#presence to check if the value is not false, is empty, or a whitespace string:
{ condition: "" }[:condition].presence || (0..Float::INFINITY)
=> 0..Infinity
otherwise its okay to return all
As I understand you need different scopes depend on condition
You can use chaining in that case
For example
models = Model.all
models = models.where(condition: params[:condition]) if params[:condition]
So if params[:condition] is truthy: some where scope will be used
If not: all records will be used
It's not one liner. But quite convenient
row = {"joining_date"=>"18/07/2015", "name"=>" Joe Doe ", "company"=>" Google", "location"=>" New York ", "role"=>"developer", "email"=>"joe#doe.com", "mobile"=>"11-(640)123-45674", "address"=>"4 XYZ Road", "validity"=>"true"}
row is invalid only if any one of the fields(joining_date, name, company, location, email, address) is nil or not present.
def is_valid?
valid = true
if row[:name] == nil || row[:joining_date] == nil || row[:address] == nil || row[:email] == nil || row[:company] == nil || row[:location] == nil
valid = false
end
valid
end
Is there any way that I can simplify and refactor the above method in rails to find it more efficient using regex?
Probably, but I wouldn't use a regex as it's in a hash. As you're using rails you can use present? or blank?.
row.values.any?(&:blank?)
Would return true if any are blank
for your case
def is valid?
row.values.all?(&:present?)
end
I have a show page for my Users and each attribute should only be visible on that page, if it is not nil and not an empty string. Below I have my controller and it is quite annoying having to write the same line of code #user.city != nil && #user.city != "" for every variable. I am not too familiar with creating my own methods, but can I somehow create a shortcut to do something like this: #city = check_attr(#user.city)? Or is there a better way to shorten this procedure?
users_controller.rb
def show
#city = #user.city != nil && #user.city != ""
#state = #user.state != nil && #user.state != ""
#bio = #user.bio != nil && #user.bio != ""
#contact = #user.contact != nil && #user.contact != ""
#twitter = #user.twitter != nil && #user.twitter != ""
#mail = #user.mail != nil && #user.mail != ""
end
There's a method that does this for you:
def show
#city = #user.city.present?
end
The present? method tests for not-nil plus has content. Empty strings, strings consisting of spaces or tabs, are considered not present.
Since this pattern is so common there's even a shortcut in ActiveRecord:
def show
#city = #user.city?
end
This is roughly equivalent.
As a note, testing vs nil is almost always redundant. There are only two logically false values in Ruby: nil and false. Unless it's possible for a variable to be literal false, this would be sufficient:
if (variable)
# ...
end
This is preferable to the usual if (!variable.nil?) or if (variable != nil) stuff that shows up occasionally. Ruby tends to wards a more reductionist type of expression.
One reason you'd want to compare vs. nil is if you have a tri-state variable that can be true, false or nil and you need to distinguish between the last two states.
You can use .present? which comes included with ActiveSupport.
#city = #user.city.present?
# etc ...
You could even write it like this
def show
%w(city state bio contact twitter mail).each do |attr|
instance_variable_set "##{attr}", #user[attr].present?
end
end
It's worth noting that if you want to test if something is blank, you can use .blank? (this is the opposite of .present?)
Also, don't use foo == nil. Use foo.nil? instead.
How do I do something like this?
if params[:property] == nil
#item.property = true
else
#item.property = false
Always forget the proper syntax to write it in one line.
In PHP it would be like this:
#item.property=(params[:property]==nil)true:false
Is it the same in rails?
use the ternary operator:
#item.property = params[:property] ? true : false
or force a boolean conversion ("not not" operation) :
#item.property = !!params[:property]
note : in ruby, it is a common idiom not to use true booleans, as any object other than false or nil evaluates to true.
m_x answer is perfect but you may be interested to know other ways to do it, which may look better in other circumstances:
if params[:property] == nil then #item.property = true else #item.property = false end
or
#item.property = if params[:property] == nil then true else false end
I have a module:
module Voteable
def has_up_vote_of user
return ! self.votes.select{|v| v.user.id == user.id && v.value == 1}.empty?
end
def has_down_vote_of user
return ! self.votes.select{|v| v.user.id == user.id && v.value == -1}.empty?
end
end
Which is mixed into a model:
class Comment < ActiveRecord::Base
include Voteable
end
In a controller code, there is a check:
has_up_vote = #voteable.has_up_vote_of #user
has_down_vote = #voteable.has_down_vote_of #user
#voteable and #user are existing model items, found in a DB.
Suppose, voteable item has up-vote of user. After executing the code, has_up_vote will be equal to true, and has_down_vote will be nil.
Why nil, instead of false ?
I have used several variations of methods, but the problem is the same. Even this gives me the same effect:
def has_up_vote_of user
has = self.votes.select{|v| v.user.id == user.id && v.value == 1}.empty?
return !has.nil? && has
end
Posssible, i'm misunderstanding something, but this behavior is strange
Update
I've noticed very strange behaviour.
When i change methods to trivial:
def has_up_vote_of user
return false
end
def has_down_vote_of user
return false
end
They both returns nil, when i debug the app.
But, from console, they returns false.
It's more stange, because i cannot do anything with these results. These code is not working:
has_up_vote = false if has_up_vote.nil?
has_down_vote = false if has_down_vote.nil?
I think that the debugging environment you're running in is interfering with the actual value of has_down_votes. The select method should never return nil as defined.
Instead of !{}.empty? you could use {}.present?
Its more readable and the output will always be true/false only
I know this doesn't get to the root cause of your strange problem, but it should give you the results you want. Instead of
return ! self.votes.select{|v| v.user.id == user.id && v.value == -1}.empty?
try
return !!self.votes.select{|v| v.user.id == user.id && v.value == -1}.any?
The double exclamation point is intentional -- it will cause nil to become false. (!arr.empty? is equivalent to arr.any? which is equivalent to !!arr.any? -- except the last one converts the nil to false)