Compare checkbox with boolean

419 views
Skip to first unread message

Linus Pettersson

unread,
Jul 25, 2011, 10:43:11 AM7/25/11
to rubyonra...@googlegroups.com
Hi!

I have a form with a checkbox called "status" which is a boolean in the database.

In my controller's update action I want to check if the checkbox has changed. Something like this:

if @item.status != params[:item][:status]
  params[:item][:position] = nil
end

But this doesn't work as the params[:item][:status] is "0" (an int as a string)
And the @item.status is false/true (a bool)

I have tried to use the .to_i on the status param to make it into an int, but it still doesn't work. I guess there is no .to_bool? :)

So, how do I do this comparison? I'm new to Rails and these small things makes be a bit puzzled :)




Fernando Almeida

unread,
Jul 25, 2011, 10:49:15 AM7/25/11
to rubyonra...@googlegroups.com
Tried to use .to_i on the both?


2011/7/25 Linus Pettersson <linus.pe...@gmail.com>



--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/P7BRyWdhMwwJ.
To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.



--
Fernando Almeida
www.fernandoalmeida.net

Linus Pettersson

unread,
Jul 25, 2011, 11:20:47 AM7/25/11
to rubyonra...@googlegroups.com
Yes, it gives me this error:
NoMethodError (undefined method `to_i' for false:FalseClass):

Fernando Almeida

unread,
Jul 25, 2011, 12:20:06 PM7/25/11
to rubyonra...@googlegroups.com
Try @item.status != !params[:item][:status].to_i.zero?



2011/7/25 Linus Pettersson <linus.pe...@gmail.com>
Yes, it gives me this error:
NoMethodError (undefined method `to_i' for false:FalseClass):

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/aQi0DLBhzIQJ.

To post to this group, send email to rubyonra...@googlegroups.com.
To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.



--
Fernando Almeida
www.fernandoalmeida.net

Linus Pettersson

unread,
Jul 25, 2011, 1:18:15 PM7/25/11
to rubyonra...@googlegroups.com
Yes, ended up doing this:
!@item.status != params[:item][:status].to_i.zero?

But it looks very ugly to me...

Tom Meinlschmidt

unread,
Jul 25, 2011, 1:29:39 PM7/25/11
to rubyonra...@googlegroups.com
after update do

if @item.status_changed? ...

> --
> You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.

> To view this discussion on the web visit https://groups.google.com/d/msg/rubyonrails-talk/-/P7BRyWdhMwwJ.


> To post to this group, send email to rubyonra...@googlegroups.com.
> To unsubscribe from this group, send email to rubyonrails-ta...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en.

--
===============================================================================
Tomas Meinlschmidt, MS {MCT, MCP+I, MCSE, AER}, NetApp Filer/NetCache

www.meinlschmidt.com www.maxwellrender.cz www.lightgems.cz
===============================================================================

Linus Pettersson

unread,
Jul 25, 2011, 1:54:28 PM7/25/11
to rubyonra...@googlegroups.com
Hmm, that seems to always return false over here.
I tried this:
update_was_successful = @item.update_attributes(params[:item])
puts @item.status_changed?

Which outputs false, always. The weird thing is that it prints that before the update is shown in the console. I guess that is why it's always false.

Isn't the update_attributes method updating the item right away?

Sandy

unread,
Jul 25, 2011, 2:08:20 PM7/25/11
to Ruby on Rails: Talk
Since the params will give you either "0" or "1" as a string, and
since you are trying to equate "0" (string) to "false" (boolean), why
not set a variable equal to "true" or "false" based on the params?
Try:

if params[:item][:status] == "0"
bool = false
else
bool = true
end

or,

bool = (params[:item][:status] != "0")

You can then compare bool to your boolean.



On Jul 25, 1:54 pm, Linus Pettersson <linus.petters...@gmail.com>
wrote:

Linus Pettersson

unread,
Jul 25, 2011, 2:29:58 PM7/25/11
to rubyonra...@googlegroups.com
Yes, but that doesn't look very good either. Not much better than doing this I'm afraid:

Hassan Schroeder

unread,
Jul 25, 2011, 2:32:40 PM7/25/11
to rubyonra...@googlegroups.com
On Mon, Jul 25, 2011 at 11:08 AM, Sandy <sandy...@gmail.com> wrote:
> Since the params will give you either "0" or "1" as a string, and
> since you are trying to equate "0" (string) to "false" (boolean), why
> not set a variable equal to "true" or "false" based on the params?

Or put something like this in an initializer:
--------------------
class String

def true?
( self == "1" || self == "true" ) ? true : false
end

def false?
!self.true?
end

end
--------------------

Then you can more readably check e.g. params[:item][:status].true?

FWIW,
--
Hassan Schroeder ------------------------ hassan.s...@gmail.com
http://about.me/hassanschroeder
twitter: @hassan

lmetcalfe

unread,
Jul 25, 2011, 2:59:09 PM7/25/11
to Ruby on Rails: Talk


On Jul 25, 2:32 pm, Hassan Schroeder <hassan.schroe...@gmail.com>
wrote:
> On Mon, Jul 25, 2011 at 11:08 AM, Sandy <sandy.as...@gmail.com> wrote:
> > Since the params will give you either "0" or "1" as a string, and
> > since you are trying to equate "0" (string) to "false" (boolean), why
> > not set a variable equal to "true" or "false" based on the params?
>
> Or put something like this in an initializer:
> --------------------
> class String
>
>   def true?
>     ( self == "1" || self == "true" ) ? true : false
>   end
>
>   def false?
>     !self.true?
>   end
>
> end
> --------------------
>
> Then you can more readably check e.g.   params[:item][:status].true?
>
> FWIW,
> --
> Hassan Schroeder ------------------------ hassan.schroe...@gmail.comhttp://about.me/hassanschroeder
> twitter: @hassan

Or this may be helpful:

def convert_to_boolean(value)
return [true, "true", 1, "1", "T", "t"].include?(value.class ==
String ? value.downcase : value)
end

Matt Jones

unread,
Jul 26, 2011, 10:06:07 AM7/26/11
to Ruby on Rails: Talk


On Jul 25, 10:43 am, Linus Pettersson <linus.petters...@gmail.com>
wrote:
> Hi!
>
> I have a form with a checkbox called "status" which is a boolean in the
> database.
>
> In my controller's update action I want to check if the checkbox has
> changed.

No, you really shouldn't be doing that in the controller. You almost
certainly want to do this in a before_save (or possibly
before_validation) callback on the MODEL.

Several reasons:

- it's a best practice to keep business logic in the model ("fat
model / skinny controller")

- inside the model callbacks, you've got access to both typecast data
(the incoming status will already have the right type) and the
_changed? predicate. For instance, your code could be shortened to:

class Item < ActiveRecord::Base

before_save :update_position

def update_position
self.position = nil if status_changed?
end

end

Not only does it avoid the messy conversion, it (IMHO) is far more
readable.

--Matt Jones

Linus Pettersson

unread,
Jul 26, 2011, 11:26:18 AM7/26/11
to rubyonra...@googlegroups.com
That is very true. Thank you for that!

I ended up changing the behavior though, so I didn't need to check if the status had changed at all.

Best Regards
Linus
Reply all
Reply to author
Forward
0 new messages