views:

76

answers:

5

I'm working on a Rails application where I have some a set of two radio buttons where users can click "yes" or "no". The MySQL DB column created by the ActiveRecord migration is a tinyint.

If the user doesn't click either radio button I want MySQL to store NULL. (The column allows NULL.) And when they come back to edit the data, neither button should be checked.

What's happening is that ActiveRecord is storing 0 and then when I come back the "No" button is checked.

Rails 2.3.5

Form code (I'm using Haml):

        = f.radio_button( :model_attribute, true )
        Yes

        = f.radio_button( :model_attribute, false )
        No

(In retrospect it probably would have been better to use a single checkbox, but it would be difficult to change that now.)

+1  A: 

How about adding :default => null to the ActiveRecord migration for the column?

John Topley
Thanks, the default col value is currently `NULL`. (The schema has outgrown its migrations.)
Ethan
+1  A: 

I ran into a problem like this with ASP.NET MVC. Since null is essentially a third possible state, I added a third hidden radio button that is selected by default. When my response contained the "null" radio button response, I manually set it. I'm not sure if this is exactly what you are going for or not, but it worked quite well for my situation.

NickLarsen
+1  A: 

This seems to defeat the idea of radio buttons (i.e., choose one out of a set). If it is important to track "no response", then would it be possible to add a third radio button for this option? If you don't want the user selecting a response and then re-selecting "no response", you can selectively choose to display the button on your form based on its current value.

bta
Good idea. I'll see if it's acceptable.
Ethan
+1  A: 

I just checked it myself and it just works as you want. Are you sure there's no code in your update action or your model that changes the attribute? If there's no radio selected in your form, the params hash will have no value for that attribute and the record will keep its previous value. Check you model for an attribute writer method or callback methods.

Teoulas
Yeah, now that I look at the SQL it looks as though ActiveRecord is inserting `NULL` for those empty radio buttons. It's hard to sort out because there are well over 100 cols. I'm going to look closer. Thanks. (There are definitely no callbacks I wrote. Maybe something on some other layer.)
Ethan
+1  A: 

Judging from your response to my comment that seems to be the behavior you want so this doesn't seem to be a UI problem but instead a problem with your model. It looks to me that calling YourModel.create() would create a DB entry with a 0 in the column.

Possibly you could fix this by defaulting model attribute to nil in your constructor because it appears that ActiveRecord will default it to false for you.

class YourModel
  def initialize
    self.model_attribute = nil
  end
end

However, if you really want 3 options Yes, Not or Not Set then you should probably just change model_attribute from a boolean to an "enum" where 0 means "Not Set", 1 means "Yes" and 2 means "No".

Randy Simon
Yeah, I may go with three options like that. Seems practical. I'll have to check with the business users to see if it would be OK.
Ethan