Reputation: 47611
I have a scenario where I'm specifically looking for a String
with the value of "nil"
. In short, I have a conditional where I want to pass nil
if the user selects that option in the dropdown and not pass "nil"
, which is what gets passed in the params:
My Select:
<select name="parent_id">
<option name="All">All</option>
<option name="None" value="nil">None</option>
</select>
My condition:
if params[ :parent_id ].present?
Child.where( parent_id: params[ :parent_id ] ) # I want this to be IS NULL when params[ :parent_id ] == "nil"
end
Typically, you would use .nil?
or .blank?
on a String
to check for a nil
value or an empty String
. But "nil".nil?
and "nil".blank?
both equal false
, as they should.
So I'm curious if there's a good way to check for a String
being "nil"
.
Currently I'm using myString == "nil"
but that leads to things like ( myString == "nil" ? nil : myString )
.
if params[ :parent_id ].present?
parent_id = params[ :parent_id ] == "nil" ? nil : params[ :parent_id ]
Child.where( parent_id: parent_id )
end
That's fine when it's used once in a while but if this is being used frequently, it's not ideal.
This a fairly rare occurrence, I know, but it was particularly difficult to Google so I thought I would ask SO.
My initial thoughts are:
String
so you could do something like "nil".nil_literal? #=> true
..presence?
so that "nil".presence?
returns nil
instead of "nil"
.Upvotes: 3
Views: 553
Reputation: 29598
This is how I would go about it
class Child
belongs_to :parent
scope :by_parent, ->(parent_id=nil) {
parent_id.to_i == 0 ? without_parent : where(parent_id: parent_id.to_i)
}
scope :without_parent, -> { where(parent_id: nil) }
end
then your controller code is simply
Child.by_parent(params[:parent_id])
Upvotes: 0
Reputation: 23347
I'd suggest to change the select to:
<option name="None" value="">None</option>
If you can't do it - I'd refrain from monkey patching.
You can add "nil"
checking to conditions:
if params[ :parent_id ].present? && params[ :parent_id != 'nil'
Child.where(parent_id: params[:parent_id]))
end
or you can filter the params
in a separate method:
def filtered_params
@filtered_params |= params.tap{|p| p[:parent_id] = nil if p[:parent_id] == 'nil' }
end
and use filtered_params
instead of params
in your controller code.
Upvotes: 1