Can't use where on a column with nil value - ruby-on-rails

I have an Article model
Article.last.publish
=> nil
Article.last.publish != true
=> true
Article.where("publish != ?", true)
=> []
Why am I getting an empty array there?

There are only 2 falsy values in ruby : false and nil
So, if you check the value of !nil then the output will be true
So with your first statement
Article.last.publish # its output is nil
Then your second statement
Article.last.publish != true # this is correct , since !nil = true
But the last one
Article.where("publish != ?", true)
gets converted into a query as
SELECT `articles`.* FROM `articles` WHERE (publish != 1)
which means all articles whose publish value is not true, which means false
and false is not equal to nil.
nil and false are two different falsy values.

Try Article.where(publish: false)

Related

Lua, if statement idiom fails to return proper boolean

local a = (true==true) and false or nil -- returns nil
local a = (true==true) and true or nil -- returns true
local a = (true==true) and not false or nil -- returns true
local a = (true==true) and not true or nil -- returns nil
Returns proper boolean when value is true, but fails when false. Why?
The boolean idiom works by using short-cut evaluation (only evaluate the second operand when necessary).
If you rewrite the expressions with explicit precedence you can see why you would get nil:
(true and false) or nil => false or nil => nil
(true and true) or nil => true or nil => true
(true and not false) or nil => true or nil => true
(true and not true) or nil => false or nil => nil
The Logical Operators section of Programming in Lua explains the idiom:
Another useful idiom is (a and b) or c (or simply a and b or c, because and has a higher precedence than or), which is equivalent to the C expression
a ? b : c
provided that b is not false. For instance, we can select the maximum of two numbers x and y with a statement like
max = (x > y) and x or y
Why can b not be false? Because the evaluation will always return false.
1 > 0 and false --> false
1 < 0 and false --> false

Ruby - loop to check if at least one pair of values are populated

So in my rails form there are several rows of 2 textfields. For the form to save ok, at least one of the pair of textfields needs to be filled out.
So
nil nil
10 20
nil nil
nil nil
is valid.
This:
nil nil
nil nil
nil nil
nil nil
is invalid
This:
nil 10
nil nil
nil nil
nil nil
is invalid
Here is the method I am using to check all the fields (note that single_field and aggregate_field are strings and are the field names):
def no_values_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.each do |item|
return false if "!item.#{single_field}".nil? && "!item.#{aggregate_field}".nil?
end
true
end
But I guess this doesn't work as it will return true or false several times and will determine that a row is invalid even though a previous row may have been valid.
I need an overall true or false.
How can this be achieved?
Try leveraging any? or none? from the Enumerable module.
Your code could be rewritten as
def no_values_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.none? { |item|
!(item.send(single_field).nil?) && !(item.send(aggregate_field).nil?)
}
end
although I think that it would be clearer to have the condition be positive and to return true when there is a match found. I would write
def any_pairs_present?(single_field, aggregate_field)
self.lo_item.lo_line_items.any? { |item|
!(item.send(single_field).nil?) && !(item.send(aggregate_field).nil?)
}
end
Note that "!item.#{single_field}" will never be nil because it will always be a string! If you want to access instance fields dynamically then one way to do that is with send, but for other options you could look here which suggests the alternatives of instance_eval and instance_variable_get.
The function looks ok, but there seems to be syntax errors, I'd also make a few amendments:
def form_valid?(single_field, aggregate_field)
self.lo_item.lo_line_items.each do |item|
return true if !item.send(single_field).nil? && !item.send(aggregate_field)
end
false
end

Why .where(:attribute => nil) checks for nil value?

So here is the query, very simple:
field = :has_bill
value = nil
scoped.where(field => value)
And it outputs as:
(`electricity_profile_segment_summaries`.`has_swimming_pool` IN ('') OR `electricity_profile_segment_summaries`.`has_swimming_pool` IS NULL)
Which includes nil values and 0 values as well. Which is not correct, I would like to represent only NULL values from the table.
Any help appreciated
How about manually limiting to NULL for the nil case?
if value.nil?
scoped.where( "#{field} IS NULL" )
else
scoped.where( field => value
end

How do you return a boolean value for a regexp scan of an integer?

I'm looking through my object attributes for culprits that are not :
^[1-3]{3}$
What is the method used to scan integers for regexp?
Some examples:
124.to_s.match(/^[1-3]{3}$/)
=> nil
123.to_s.match(/^[1-3]{3}$/)
=>#<MatchData "123">
Since nil is considered as false, you have your boolean.
Ex:
"no yo" if 124.to_s.match(/^[1-3]{3}$/)
=> nil
"yo!" if 123.to_s.match(/^[1-3]{3}$/)
=> "yo!"
You may use also one of the following:
def is_pure_integer?(i)
i.to_i.to_s == i.to_s
end
or
'132' =~ /^\d+$/ ? true : false

Lua unpack bug?

I Have stumbled on a weird behavior in Lua unpack function
table1 = {true, nil, true, false, nil, true, nil}
table2 = {true, false, nil, false, nil, true, nil}
a1,b1,c1,d1,e1,f1,g1 = unpack( table1 )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)
a2,b2,c2,d2,e2,f2,g2 = unpack( table2 )
print ("table2:",a2,b2,c2,d2,e2,f2,g2)
Output:
table1: true nil true false nil nil nil
table2: true false nil nil nil nil nil
The second unpack delivers parameters up to the first nil value. I could live with that.
The first table delivers 4? parameters with one being nil in the middle. It has 4 parameters that are not nil, but they aren't the one that are shown.
Could anyone explain this?
This was tried with codepad.org and lua 5.1
The problem can be resolved simply by specifying the beginning and ending indexes to unpack() and using the table.maxn() as the ending index:
table1 = {true, nil, true, false, nil, true, nil}
a1,b1,c1,d1,e1,f1,g1 = unpack( table1, 1, table.maxn(table1) )
print ("table1:",a1,b1,c1,d1,e1,f1,g1)
-->table1: true nil true false nil true nil
The true reason for the discrepancy on how the two tables are handled is in the logic of determining the length of the array portion of the table.
The luaB_unpack() function uses luaL_getn() which is defined in terms of lua_objlen() which calls luaH_getn() for tables. The luaH_getn() looks at the last position of the array, and if it is nil performs a binary search for a boundary in the table ("such that t[i] is non-nil and t[i+1] is nil"). The binary search for the end of the array is the reason that table1 is handled differently then table2.
This should only be an issue if the last entry in the array is nil.
From Programming in Lua (pg.16) (You should buy this book.):
When an array has holes--nil elements inside it--the length operator may assume any of these nil elements as the end marker. Therefore, you should avoid using the length operator on arrays that may contain holes.
The unpack() is using the length operator lua_objlen(), which "may assume any of [the] nil elements as the end" of the array.
2.2 - Values and Types
[...]
The type table implements associative
arrays, that is, arrays that can be
indexed not only with numbers, but
with any value (except nil). Tables
can be heterogeneous; that is, they
can contain values of all types
(except nil). [...]
Given nil to an entry will break the table enumeration and your variables wont be init properly.
Here is a simple example that demonstrates a problematic behavior:
table1 = {true, false, nil, false, nil, true, nil}
for k,v in ipairs(table1) do
print(k, v)
end
output:
1 true
2 false
>Exit code: 0

Resources