Reputation: 7038
I'm trying to figure out if there is an easy way to do the following short of adding to_i method to TrueClass/FalseClass.
Here is a dilemma: I have a boolean field in my rails app - that is obviously stored as Tinyint in mysql. However - I need to generate xml based of the data in mysql and send it to customer - there SOAP service requires the field in question to have 0 or 1 as the value of this field. So at the time of the xml generation I need to convert my False to 0 and my True to 1 ( which is how they are stored in the DB). Since True & False lack to_i method I could write some if statement that generate either 1 or 0 depending on true/false state. However I have about 10 of these indicators and creating and if/else for each is not very DRY. So what you recommend I do?
Or I could add a to_i method to the True / False class. But I'm not sure where should I scope it in my rails app? Just inside this particular model or somewhere else?
Upvotes: 6
Views: 5672
Reputation: 20086
You can use:
5 - bool.to_s.length
This will always work because true.to_s
is "true"
and false.to_s
is "false"
, and "true".length
is 4, while "false".length
is 5.
Upvotes: 0
Reputation: 47471
humanize
and to_i
.This comes up in most of my projects so I use an initializer (if you're using Rails) that adds these two helpful methods to each class, like so:
config/initializers/true_and_false.rb
class TrueClass
def humanize
'Yes'
end
def to_i
1
end
end
class FalseClass
def humanize
'No'
end
def to_i
0
end
end
Then it makes rendering true
very easy for both "human consumption" and "machine consumption":
> true.humanize #=> Yes
> true.to_i #=> 1
> false.humanize #=> No
> false.to_i #=> 0
Upvotes: 5
Reputation: 468
Update: This 'solution' is dangerous and should not be used!
You can also try:
value.object_id / 2
I'm not sure how well this works across implementations.
To get rid of the duplication of having to repeat this 10 times, I would still recommend creating a method:
def boolean_to_i value
value.object_id / 2
end
No real need to monkey-patch, though.
Upvotes: 2
Reputation: 410592
You could create a file such as lib/boolean_ints.rb
and monkey-patch a to_i
method to TrueClass
and FalseClass
, as you suggested. Then, in the models or controllers in which you need to use the to_i
method, you could just put
require 'boolean_ints'
at the top, and they'd be available for use.
Upvotes: 5
Reputation: 258148
You could just monkeypatch the TrueClass
and FalseClass
in your app, near that particular model: any implementation of to_i
on true and false are likely to be the same.
irb(main):004:0> true.to_i
NoMethodError: undefined method `to_i' for true:TrueClass
from (irb):4
irb(main):005:0> class TrueClass
irb(main):006:1> def to_i
irb(main):007:2> 1
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0>
irb(main):011:0* true.to_i
=> 1
But to avoid monkeypatching, is there any reason you couldn't just use the ternary operator? If that's still not DRY enough for you, wrap it up in a method.
irb(main):012:0> true ? 1 : 0
=> 1
irb(main):013:0> false ? 1 : 0
=> 0
Of course, that works with non-boolean variables as well:
irb(main):019:0* 1234 ? 1 : 0
=> 1
irb(main):020:0> nil ? 1 : 0
=> 0
Upvotes: 3