many_to_many associations in rails
This has been a nightmare for me and I'm willing to give an arm and an eyeball to the person who can help me :P I'm going to explain this as best as possible.
When a user edits their 'profile' they can type in skills that they have in nested attributes fields (they can click 'Add Another Skill' an开发者_开发知识库d it will populate another field for them to type). When they begin to type, jquery-autocomplete kicks in. They MUST select an item from autocomplete. When they save, for example, 3 skills, we get this:
table: skills
+-----------+----------------+
| user_id | skill |
+-----------+----------------+
| 4 | Photoshop |
+-----------+----------------+
| 4 | Illustrator |
+-----------+----------------+
| 4 | InDesign |
+-----------+----------------+
Now, what I want to do is NOT store the actual skill names. Instead, I want to store the ID of the skill from skills_vocabulary
list (which is what the jquery-autocomplete uses).
table: skills_vocabulary
+------+----------------+
| id | skill |
+------+----------------+
| 1 | Illustrator |
+------+----------------+
| 2 | Dreamweaver |
+------+----------------+
| 3 | After Effects |
+------+----------------+
| 4 | InDesign |
+------+----------------+
| 5 | Photoshop |
+------+----------------+
| 6 | Flash |
+------+----------------+
THUS, the skills
table should look like this:
+-----------+----------------+
| user_id | skill_id |
+-----------+----------------+
| 4 | 5 |
+-----------+----------------+
| 4 | 1 |
+-----------+----------------+
| 4 | 4 |
+-----------+----------------+
Any help would be greatly, greatly, greatly appreciated. I've been at war with this for an embarrassing 3 months.
Thank you all.
EDIT/
<%= f.fields_for :skills do |builder| %>
<%= render "skills_fields", :f => builder %>
<% end %>
<p><%= link_to_add_fields "Add a Skill", f, :skills %></p>
_skills_fields.html.erb
<div class="fields ac skills">
<div class="clearfix">
<span class="left"><%=f.autocomplete_field :name, users_autocomplete_skills_vocab_name_path, :class => 'restricted_to_autocomplete' %></span><span class="remove_link left"><%= link_to_remove_fields "[x]", f %></span>
</div>
</div>
EDIT 2/
Right now it's just
skill.rb
class Skill < ActiveRecord::Base
belongs_to :user
end
user.rb
class User < ActiveRecord::Base
has_many :tskills, :dependent => :destroy
accepts_nested_attributes_for :tskills, :allow_destroy => true, :reject_if => lambda { |a| a[:name].blank? }
end
skills_vocabulary.rb
class SkillsVocabulary < ActiveRecord::Base
end
My controller code is the basic index, show, new, create, update, destroy
The list of skills (about 10,000 items long) is in the table skills_vocabularies
This should be your classes:
class User < ActiveRecord::Base
has_and_belongs_to_many :skills
end
class Skill < ActiveRecord::Base
has_and_belongs_to_many :users
end
and this is the migration which creates them
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :users
end
end
class CreateSkills < ActiveRecord::Migration
def self.up
create_table :skills do |t|
t.string :name
t.timestamps
end
end
def self.down
drop_table :skills
end
end
class SkillsUsers < ActiveRecord::Migration
def self.up
create_table :skills_users, :id => false do |t|
t.integer :skill_id
t.integer :user_id
end
end
def self.down
drop_table :skills_users
end
end
then add a new skill is as simple as
user.skills << Skill.find(1) # to add a skill
user.skills = Skill.all # to add many of them
Look here fo further details
Update: I ve tried the autocomplete gem and I think you should accept the Rubish Gupta suggestion, i.e. use my models plus jquery token input because it will handle pretty well many-to-many associations. Autocomplete gem as far as I saw is for 1-to-n associations.
Moreover you have a full working example in rails to play with.
精彩评论