简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM