2011-07-27 44 views
0

這對我來說是一場噩夢,我願意爲能夠幫助我的人提供一隻手臂和一隻眼球:P我將盡可能地解釋這一點。many_to_many associations in rails

當用戶編輯他們的'個人資料'時,他們可以輸入他們在嵌套屬性字段中的技能(他們可以點擊'添加另一個技能',它將填充另一個字段供他們輸入)。當他們開始鍵入時,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個月。

謝謝大家。

編輯/

<%= 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/

現在它只是

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 

我的控制器代碼是最基本的指標,顯示,新,創建,更新,破壞

的技能列表(約10000項長)是表skills_vocabularies

+1

我會建議你使用http://loopj.com/jquery-tokeninput/。還有一個railscast:http://railscasts.com/episodes/258-token-fields。如果沒有,請查看https://github.com/crowdint/rails3-jquery-autocomplete的代碼,並開始更改相關內容。 – rubish

+0

你也可以看看SO問題(http://stackoverflow.com/questions/6727183),同時添加技能,同時自動完成它們。這比用戶再次點擊來添加一項新技能 – rubish

+0

@Rubish我實際上正在使用rails3-jquery-autocomplete - 我們可能決定讓他們添加那些不在自動完成中的東西,並將其自動添加到數據庫中。這只是對詞彙表的引用令我感到困擾。 – stewart715

回答

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 FO進一步的細節

更新:我已經盡力了自動完成的寶石,我想你應該接受Rubish古普塔建議,即使用我的模型加上jquery token input,因爲它可以很好地處理多對多的關聯。就我所見,自動完成寶石是用於1對n的關聯。

此外,你有一個full working example在軌道上玩。

+0

謝謝,不知道這將工作,但我已經設置了。我用我的表單域編輯了我的問題。這些會起作用嗎? – stewart715

+0

我不知道rails3-jquery-autocomplete寶石,所以我不能直接回答你的問題。順便說一句,我認爲我的例子將適合您的需求,因爲它只涉及服務器部分。所以你應該用控制器和型號代碼更新你的問題。 – Fabio

+0

再次編輯...非常感謝您花時間。 jquery gem只是自動完成文本字段 - 它保存的位置與其他任何普通文本字段相同。 – stewart715