0

これらは問題のモデルです

SkillProgession
belongs_to :skill
belongs_to :user

User
has_many :skill_progressions
has_many :skills, :through => :skill_progressions

def has_progression?(skill)
   SkillProgression.where(:skill_id => skill.id, :user_id => id).first
end

Skill
has_many :skill_progressions
has_many :users, :through => :skill_progressions

アプリケーションでは、ユーザーは複数のスキルを持つことができ、スキルは複数のユーザーに関連付けることができます。各ユーザーとスキルの間に1 つの関係のみが存在することが重要です。これは、追加の情報を後の段階 (つまり、「コンピタンス」など) に保存する必要があるためです。

データベースが重複行を許可しないようにするためのインデックスがあります(これは本当に必要ですか?)

add_index :skill_progressions, [:skill_id, :user_id ], :unique => true, :name => 'by_skill_and_user'

この関係は、両方のモデルの外部で何かが発生した場合 (ユーザーが現在のスキルに関連するタスクへの回答を送信した場合) に追加されます。これは、次のコントローラー コードで示されています。

TaskController

def answer
   skill = Skill.find(params[:skill_id])
   @task = skill.tasks.find(params[:id])       
   unless current_user.has_progression?(skill)
     current_user.add_skill(skill, "placeholder")
   end
end

さて、これはかなりハッキーに思えますが、もっときれいにする方法が欲しいです。コントローラーで次のコードを使用できると思います

skill_progression = SkillProgression.find_by_user_id(current_user.id)
current_user.skill_progressions.include? skill_progression

しかし、これはそれを行うためのより効率的またはエレガントな方法でしょうか?

これに関する助けがあれば大歓迎です:-) デザインアプローチ全体を再考する必要があるとしても、それをエレガントにしたいだけです!

4

1 に答える 1

3

skill_progression モデルに検証を追加できます

validates :skill_id, uniqueness: { scope: :user_id }

user_idこれを追加すると、同じとを持つ 2 つの skill_progress レコードが作成されなくなりskill_idます。ただし、これを回避する方法はたくさんあることに注意してください。

于 2013-03-15T13:28:52.910 に答える