Rails 3 has_many through checkbox form doesn't (does not) work
I have been stuck on this for a day now. I've heard all of this talk of Rails being able to handle easy complexities like this (although this isn't/shouldn't 开发者_开发技巧be complex).
Story: User can have many advanced degrees. I want to be able to create this association using a has_many through relationship and use checkboxes in my view.
Models:
class User < ActiveRecord::Base
has_many :user_degree_lists
has_many :degrees, :through => :user_degree_lists, :source => :advanced_degree, :dependent => :destroy
end
class AdvancedDegree < ActiveRecord::Base
attr_accessible :value, :description
has_many :user_degree_lists
end
class UserDegreeList < ActiveRecord::Base
belongs_to :user
belongs_to :advanced_degree
end
ActiveRecord:
class CreateUserDegreeLists < ActiveRecord::Migration
def self.up
create_table :user_degree_lists do |t|
t.integer :user_id
t.integer :advanced_degree_id
t.timestamps
end
add_index :user_degree_lists, :user_id
add_index :user_degree_lists, :advanced_degree_id
add_index :user_degree_lists, [:user_id, :advanced_degree_id], :unique => true
end
def self.down
drop_table :user_degree_lists
end
end
View:
<%= form_for(@user, :html => {:autocomplete => 'off', :id => "sign_up_user" }) do |f| %>
...
<% for advanced_degree in AdvancedDegree.find(:all)%>
<%= check_box_tag "user[advanced_degree_ids][]", advanced_degree.id, @user.degrees.include? (advanced_degree.id) %>
<%= f.label :advanced_degrees, advanced_degree.description %>
...
<% end %>
Once the form is submitted, all user fields are updated, but the :user_degree_lists relationship is not created.
What am I doing wrong here?
Not sure if you solved this already, but one thing I spotted: shouldn't the class User have 'has_many :advanced_degrees' versus 'has_many :degrees'? Might want to try that without the source on it (unless you're trying for something polymorphic), that's how I did something similar.
1) I would rename "UserDegreeList" to "UserDegree" since this is a join table.
2) "AdvancedDegree.find(:all)" can be "AdvancedDegree.all".
3) I agree with the previous comment and it should be renamed to "has_many :advanced_degrees"
4) To solve the issue, try adding this to User:
accepts_nested_attributes_for :advanced_degrees, :allow_destroy => true, :reject_if => :all_blank
You need to make sure that attr_accessible has the attr you are setting in the check boxes.
class Zone < ActiveRecord::Base
attr_accessible :name, :active, :user_ids
has_many :user_zones
has_many :users, :through => :user_zones
end
class User < ActiveRecord::Base
attr_accessible :name, :zone_ids
has_many :user_zones
has_many :zones, :through => :user_zones
end
精彩评论