根据 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 的 jquery TokenInput 示例,我创建了一个适当的表单,以允许用户使用 tokenInput 文本字段分配(和创建)技能。
现在的问题在于在保存关联之前处理数据和设置评估者。
通过一些 ruby 魔术,用户模型上的 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 方式”来实现这一点——编写漂亮、可读的代码呢?任何帮助将不胜感激!