I'm submitting a parameter show_all
with the value true
. This value isn't associated with a model.
My controller is assigning this parameter to an instance variable:
@show_all = params[:show_all]
However, @show_all.is_a? String
, and if @show_all == true
always fails.
What values does Rails parse as booleans? How can I explicitly specify that my parameter is a boolean, and not a string?
You can add the following to your model:
This should work nicely if you're passing the value in from a checkbox -- a missing key in a hash generates nil, which evaluates to false in a conditional.
EDIT
As pointed out here, the ternary operator is not necessary, so this can just be:
@show_all = params[:show_all] == "1"
You could convert all your boolean params to real booleans like this:
In this solution, nil parameters would become false.
Another approach is to pass only the key without a value. Although using
ActiveRecord::Type::Boolean.new.type_cast_from_user(value)
is pretty neat, there might be a situation when assigning a value to the param key is redundant.Consider the following: On my products index view by default I want to show only scoped collection of products (e.g. those that are in the stock). That is if I want to return all the products, I may send
myapp.com/products?show_all=true
and typecast theshow_all
parameter for a boolean value.However the opposite option -
myapp.com/products?show_all=false
just makes no sense since it will return the same product collection asmyapp.com/products
would have returned.An alternative:
if I want to return the whole unscoped collection, then I send
myapp.com/products?all
and in my controller defineIf the key is present in params, then regardless of its value, I will know that I need to return all products, no need to typecast value.
I wanted to comment on zetetic answer but as I can't do that yet I'll post this as an answer.
If you use
@show_all = params[:show_all] == "1"
then you can drop
? true : false
becauseparams[:show_all] == "1"
statement itself will evaluate to true or false and thus ternary operator is not needed.This question is rather old, but since I came across this issue a couple of times, and didn't like any of the solutions proposed, I hacked something myself which allows to use multiple strings for true such as 'yes', 'on', 't' and the opposite for false.
Monkey patch the class String, and add a method to convert them to boolean, and put this file in
/config/initializers
as suggested here: Monkey Patching in Rails 3Notice that if the value is none of the valid ones either for true or false, then it returns nil. It's not the same to search for
?paid=false
(return all records not paid) than?paid=
(I don't specify if it has to be paid or not -- so discard this).Then, following this example, the logic in your controller would look like this:
It's pretty neat, and helps to keep controllers/models clean.