0

Ryan Batesの優れたRailsCast#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

フォームには、IDとして渡されるスキルトークンの通常のテキストフィールドが含まれています。

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

したがって、ユーザーは機能を通じて多くのスキルを割り当てることができます。スキルを割り当てる際、評価者は能力モデルでも追跡する必要があります。

ryansのjqueryTokenInputの例を使用して、ユーザーが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ではそれほど簡単には機能しません。

では、「レールの方法」でこれを実現するにはどうすればよいでしょうか。美しく、読みやすいコードを作成するのでしょうか。どんな助けでも大歓迎です!

4

1 に答える 1

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

おそらくあなたが望んでいたほどエレガントではありませんが、それは仕事をするべきですか?

于 2012-06-28T13:04:07.160 に答える