0

我遇到了一個基於Ryan Bates的優秀RailsCast#258的問題。Railscasts 258令牌字段 - 通過表中設置附加屬性 - 導軌的方式做到這一點

的情況如下:

class User < ActiveRecord::Base 
    has_many :capabilities, 
      :dependent => :destroy 
    has_many :skills, :through => :capabilities, 
      :uniq => true 

    has_many :raters, 
      :through => :capabilities, 
      :foreign_key => :rater_id, 
      :uniq => true 

    attr_accessible :name, :skill_tokens 
    attr_reader :skill_tokens  

    def skill_tokens=(tokens) 
     self.skill_ids = Skill.ids_from_tokens(tokens) 
    end 
end 

class Capability < ActiveRecord::Base 
    belongs_to :user 
    belongs_to :rater, class_name: "User" 
    belongs_to :skill 

    validates_uniqueness_of :rater_id, :scope => [:user_id, :skill_id] 
end 

class Skill < ActiveRecord::Base 
    has_many :capabilities 
    has_many :users, :through => :capabilities, 
      :uniq => true 

    has_many :raters, :through => :capabilities, 
      :foreign_key => :rater_id 
end 

該表單包含一個正常的文本字段的技能令牌被作爲IDS通過:

.field 
    = f.label :skill_tokens, "Skills" 
    = f.text_field :skill_tokens, data: {load: @user.skills} 

這樣用戶就可以得到分配,通過功能很多技巧。在分配技能時,評估者也應該在能力模型中進行跟蹤。

使用Ryans的jquery示例TokenInput我創建了一個適當的表單,允許用戶使用tokenInput文本字段分配(並創建)技能。

現在的問題在於處理數據並在關聯保存之前設置評估者。

通過一些紅寶石魔力,用戶模型self.skill_ids設置用於關聯模型創建的ID,以便控制器動作很簡單:

def update 
    @user = User.find(params[:id]) 

    respond_to do |format| 
     if @user.update_attributes(params[:user])  
     format.html { redirect_to @user, notice: 'User was successfully updated.' } 
     format.json { head :no_content } 
     else 
     format.html { render action: "edit" } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

很顯然,如果我想設置額外的評價者屬性在能力模型上不會如此輕鬆地使用update_attributes。

那麼我怎麼能用「rails方式」來實現這一點 - 編寫美觀,可讀的代碼? 任何幫助將非常感激!

回答

0

你是如何設置rater_id

如果您打算接受評價者用戶的形式將每個技能的用戶輸入, 我看不出你就可以使用基於令牌的輸入輸入字段來實現這一目標。你將不得不選擇其他類型的輸入。

如果您計劃設置評價者對當前登錄的用戶,或者基於其他一些業務邏輯被設置評價者,我的做法是覆蓋skill_ids=方法在用戶模式來工作,你怎麼想它,添加一個attr_accessor來存儲current_rater並從控制器傳遞current_rate。

喜歡的東西:

#user.rb 
attr_accessor :current_rater 
def skill_ids=(ids) 
    return false if current_rater.nil? || User.find_by_id(current_rater).nil? 
    capabilities.where("skill_id not in (?)", ids).destroy_all 
    ids.each do |skill_id|  
    capabilities.create(:skill_id => skill_id, :rater_id => self.current_rater) if capabilities.find_by_id(skill_id).nil? 
    end 
end 

#users_controller.rb 
def update 
    @user = User.find(params[:id]) 

    #Replace 'current_user' with whatever method you are using to track the logged in user 
    params[:user].merge(:current_rater => current_user) 

    respond_to do |format| 
    ... 
    end 
end 

也許不是優雅如你所希望看到的,但它應該做的工作?

相關問題