开发者

How can I get a set of radio buttons to accept NULL (nothing checked)?

开发者 https://www.devze.com 2022-12-24 15:32 出处:网络
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

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.)


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.


Here's my take. I want the user to be able to unselect true/false and set the attribute to nil (Rails 4):

form

= f.radio_button :accepted, true
= f.radio_button :accepted, false
= f.radio_button :accepted, 'nil'

controller

def widget_params
  if params[:widget][:accepted] == 'nil'
    params[:widget][:accepted] = nil
  end
  params.require(:widget).permit(:accepted)
end


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.


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


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.


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".


I have solved this today in the following (simplified) example. It's not perfect, but it seems to work for me :) There must be a simpler way to circumvent Rails not sending through the param for radio buttons that do not have a value selected...

In the controller:

def create
  params[:post] = Post.deselect_radio_buttons(params[:post])
  @post = Post.new(params[:post])

  if @post.save
    redirect_to post_path(@post), notice: 'Post created'
  else
    render action: :new
  end
end

in the model:

# Define the fields that are used as radio buttons in the form.
RADIO_BUTTONS = [:field1, :field2]

def self.deselect_radio_buttons(params)
  RADIO_BUTTONS.each do |field|
    if params[field].blank?
      params[field] = nil
    end
  end

  return params
end
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号