Rails HABTM accepts_nested_attributes_for mapping table
- by Rabbott
Currently I have a habtm relationship between a datastream (stream), and a chart. I want to be able to use the 'typical' jquery "add new stream" method to add a new entry into a mapping table that holds the chart_id, and stream_id.. But I think that most examples out there are made to handle a one to many relationship..
The functionality provided here by Ryan Bates is what I'm looking for, But I dont want to use checkboxes, I want to use a select (drop down) to add new items to the mapping table.
I need THIS and THIS combined
chart.rb
class Chart < ActiveRecord::Base
has_and_belongs_to_many :streams, :readonly => false, :join_table => 'charts_streams'
accepts_nested_attributes_for :streams, :reject_if => lambda { |a| a.values.all?(&:blank?) }, :allow_destroy => true
stream.rb
class Stream < ActiveRecord::Base
has_and_belongs_to_many :charts, :readonly => false, :join_table => 'charts_streams'
application.js
/*
* Method used to add new child form partials
*/
$('form a.add_child').click(function() {
var assoc = $(this).attr('data-association');
var content = $('#' + assoc + '_fields_template').html();
var regexp = new RegExp('new_' + assoc, 'g');
var new_id = new Date().getTime();
var newElements = jQuery(content.replace(regexp, new_id)).hide();
$(this).parent().before(newElements).prev().slideFadeToggle();
return false;
});
/*
* Method used to remove child form partials
*/
$('form a.remove_child').live('click', function() {
if(confirm('Are you sure?')) {
var hidden_field = $(this).prev('input[type=hidden]')[0];
if(hidden_field) {
hidden_field.value = '1';
}
$(this).parents('.fields').slideFadeToggle();
}
return false;
});
_form.html.erb
<div id="streams">
<h4>Streams</h4>
<% form.fields_for :streams do |stream_form| %>
<%= render :partial => "stream", :locals => {:f => stream_form} %>
<% end %>
</div>
<p><%= add_child_link 'Add a stream', :streams %></p>
<%= new_child_fields_template(form, :streams) %>
_stream.html.erb
<div class="fields">
<p>
<%= f.label :stream_id %><br />
<%= select_tag "chart[stream_ids][]", options_for_select(@streams.map {|s| [s.label, s.id]}, f.object.id) %>
</p>
<p><%= remove_child_link 'Remove stream', f %></p>
</div>
This may be overkill and what I am looking to do could be much easier.. Basically when I create a chart I want to be able to add as many streams to it as I want, using the javascript for adding a new entry, and removing an old one... Thanks for the help!
This is 'working' but gives me a ActiveRecord::ReadOnlyRecord error when it hits the chart.update_attributes method.. am I adding the the :readonly = false in the wrong spot? Or am I just doing it completely wrong?