Nested Attributes and Radio Buttons -- any way to do this?

I have the following:

class Title
has_many :roles
has_many :people, :through => :roles
accepts nested_attributes_for :roles

(Roles and People are also correctly defined)

In my title#edit view, I have the fields_for set up correctly and
working:

<%= f.fields_for :roles do |builder| %>
<%= render “role_fields”, :f => builder %>
<%- end -%>

and in the role_fields partial, I have

<%= f.check_box :primary %>
<%= f.label :primary %>

Now I would like to change the check_box (which does work correctly)
into a radio button, so only one of the nested roles would be the
primary role. How can I use nested attributes and radio buttons?

If I replace the f.check_box call with f.radio_button( :primary,
true ) I end up with a radio group that acts like a bunch of
individual radio groups – I can click on any of them and each one
will check on without deselecting any of the others. If I change the
name, so that each button has the same name, then the radio group
works as expected, but the nested form breaks. I need those unique
index names (title[roles_attributes][0][primary],
title[roles_attributes][1][primary], title[roles_attributes][3]
[primary], etc.) to set the primary attribute on the correct nested
role.

Short of using JavaScript to enforce the one-radio-button-at-a-time
rule here, is there any way to do a nested form with radio buttons
like this?

Thanks in advance,

Walter

I’d recommend creating an attr_accessor for :primary on your Title
model.
In your form you could do something like:
f.object.roles.each do |role|
f.radio_button :primary, :role.id
f.label :primary

which should have the desired behavior.

Samantha J. wrote in post #1032986:

I’d recommend creating an attr_accessor for :primary on your Title
model.
In your form you could do something like:
f.object.roles.each do |role|
f.radio_button :primary, :role.id
f.label :primary

which should have the desired behavior.
This solution does not work with newly added nested objects as they
don’t have an ID yet (with cocoon/railscasts nested forms handling).

I’ve asked a question about the same issue here :

On Dec 26, 2012, at 12:56 PM, Gauthier D. wrote:

don’t have an ID yet (with cocoon/railscasts way nested forms handling).

I’ve asked a question about the same issue here :

I ended up solving this in my application by using an after_create hook
to set the primary person to whichever person was added first, and then
allowing the radio button to change this during any subsequent edit. The
radio buttons are not even shown until the parent record is persisted.
Not a perfect solution, but one that has actually fit into the workflow
very nicely, since the (human) editor seems to think that way (adding
the author first) while creating new titles.

Walter

Walter D. wrote in post #1090281:

On Dec 26, 2012, at 12:56 PM, Gauthier D. wrote:

don’t have an ID yet (with cocoon/railscasts way nested forms handling).

I’ve asked a question about the same issue here :

I ended up solving this in my application by using an after_create hook
to set the primary person to whichever person was added first, and then
allowing the radio button to change this during any subsequent edit. The
radio buttons are not even shown until the parent record is persisted.
Not a perfect solution, but one that has actually fit into the workflow
very nicely, since the (human) editor seems to think that way (adding
the author first) while creating new titles.

Walter
Seems that you’re the same person who answered on Stackoverflow ;o)

This workaround is unfortunately not compatible with my workflow since
my app has to be simple and fast…users will not accept a second edit
to set the main address…

The sad thing is that this is really easy to do in a hand-made
form…but I can’t get rid of nested forms that brings lots more than
this little issue!

I’m working on a JS workaround, handling “virtual” radio buttons groups,
based on “data-radio-group” attribute instead of “name”.

This is not as clean as I’d like but it’s compatible with my workflow,
and logical for the user…

In case someone is interested, here is my really simple code to handle
virtual radio buttons groups (it’s Coffeescript + jQuery) :

jQuery →
$(“input[data-radio-group]”).on ‘change’, (e) →
$(“input[data-radio-group='” + $(e.target).data(‘radioGroup’) +
“']”).attr(‘checked’, false)
$(e.target).attr(‘checked’, true)

When you change an input with “data-radio-group” arttributes, it
unchecks other inputs with same group value and checks the one changed
(so that you can’t unselect all options).

Compared to “real” radio groups, I loose the ability to quickly get the
“group value” (since all buttons have the same “true” value) but I don’t
need that in my case.

On Dec 27, 2012, at 12:14 PM, Walter Lee D. wrote:

On Dec 27, 2012, at 6:33 AM, Gauthier D. wrote:

Compared to “real” radio groups, I loose the ability to quickly get the
“group value” but I don’t need that in my case.

You might try this:

$$(‘input[data-radio-group=“foo”][checked]’).first().getValue();

Or maybe it’s

$$(‘input[data-radio-group=“foo”]:checked’).first().getValue();

Try both.

Walter

The second selector is correct. Converting it to jQuery, it’s

$(‘input[data-radio-group=“foo”]:checked’).first().val();


Dheeraj K.

On Dec 27, 2012, at 6:33 AM, Gauthier D. wrote:

Compared to “real” radio groups, I loose the ability to quickly get the
“group value” but I don’t need that in my case.

You might try this:

$$(‘input[data-radio-group=“foo”][checked]’).first().getValue();

That’s Prototype, but you should be able to translate to jQuery – they
both use Sizzle under the hood, and the selector’s the thing that
matters here.

Walter