rails中的many_to_many关联

时间:2011-07-27 14:00:29

标签: mysql sql ruby-on-rails ruby ruby-on-rails-3

这对我来说是一场噩梦,我愿意帮助那些可以帮助我的人:P我会尽可能地解释这个。

当用户编辑他们的“个人资料”时,他们可以输入他们在嵌套属性字段中的技能(他们可以点击“添加另一个技能”,它将填充另一个字段供他们输入)。当他们开始输入时,jquery-autocomplete就会启动。他们必须从自动完成中选择一个项目。当他们保存例如3种技能时,我们得到了这个:

表:skills

+-----------+----------------+
|  user_id  |     skill      |
+-----------+----------------+
|     4     |  Photoshop     |
+-----------+----------------+
|     4     |  Illustrator   |
+-----------+----------------+
|     4     |  InDesign      |
+-----------+----------------+

现在,我想要做的不是存储实际的技能名称。相反,我想从skills_vocabulary列表中存储技能的ID(这是jquery-autocomplete使用的)。

表:skills_vocabulary

+------+----------------+
|  id  |     skill      |
+------+----------------+
|  1   |  Illustrator   |
+------+----------------+
|  2   |  Dreamweaver   |
+------+----------------+
|  3   |  After Effects |
+------+----------------+
|  4   |  InDesign      |
+------+----------------+
|  5   |  Photoshop     |
+------+----------------+
|  6   |  Flash         |
+------+----------------+

那么,skills表应如下所示:

+-----------+----------------+
|  user_id  |    skill_id    |
+-----------+----------------+
|     4     |        5       |
+-----------+----------------+
|     4     |        1       |
+-----------+----------------+
|     4     |        4       |
+-----------+----------------+

任何帮助都会受到极大的赞赏。我为此感到尴尬3个月。

谢谢大家。

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>

编辑2 /

现在只是

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

我的控制器代码是基本索引,显示,新建,创建,更新,销毁

技能列表(约10,000项长)在表skills_vocabularies

1 个答案:

答案 0 :(得分:3)

这应该是你的课程:

class User < ActiveRecord::Base
  has_and_belongs_to_many :skills
end

class Skill < ActiveRecord::Base
  has_and_belongs_to_many :users
end

这是创建它们的迁移

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

然后添加新技能就像

一样简单
user.skills << Skill.find(1) # to add a skill
user.skills = Skill.all      # to add many of them

查看更多详情here

更新:我尝试了自动完成宝石,我认为你应该接受Rubish Gupta建议,即使用我的模型加上jquery token input,因为它可以很好地处理多对多关联。就我所见,自动完成宝石是1对n的关联。

此外,您还可以在导轨中使用full working example