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

在应用程序中,一个用户可以拥有多个技能,一个技能可以与多个用户相关联。重要的是每个用户和技能之间只有一个关系,因为我们希望在更进一步的阶段存储附加信息(即“能力”或其他)。

我有一个索引来确保数据库不会允许重复的行(顺便说一句,这真的有必要吗?)

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

现在,这似乎相当hacky,我想要一种让它更干净的方法。我想我可以在控制器中使用以下代码

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 }

添加这将防止创建 2 个具有相同user_id和的技能进度记录skill_id。请注意,有很多方法可以解决这个问题。

于 2013-03-15T13:28:52.910 回答