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ではそれほど簡単には機能しません。
では、「レールの方法」でこれを実現するにはどうすればよいでしょうか。美しく、読みやすいコードを作成するのでしょうか。どんな助けでも大歓迎です!