Rails has_many:通过验证嵌套记录按特定参数计算

时间:2016-04-09 12:01:22

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord has-many-through

我有模特锻炼和用户通过模型相关多少 UserWorkout。并且模型UserWorkout具有属性:is_creator,其显示用户是创建者。但是锻炼应该只有一个创造者。添加此类验证的最佳方法是什么?

 class Workout < ActiveRecord::Base

  has_many :user_workouts, inverse_of: :workout, dependent: :destroy
  has_many :participants, through: :user_workouts, source: :user

  def creator
    participants.where(user_workouts: { is_creator: true }).order('user_workouts.created_at ASC').first
  end

end

class UserWorkout < ActiveRecord::Base

  belongs_to :user
  belongs_to :workout

end

class User < ActiveRecord::Base

  has_many :user_workouts, inverse_of: :user, dependent: :destroy
  has_many :workouts, through: :user_workouts

end

2 个答案:

答案 0 :(得分:2)

您可以在workout_id where is_creator = true

上添加filtered/partial index,具体取决于您的DBMS

在有效记录级别,您可以添加custom validation

class UserWorkout
  validate :workout_has_only_one_creator

  private

  def workout_has_only_one_creator
    if self.class.find_by(workout_id: workout_id, is_creator: true)
      errors.add(:is_creator, 'can only have one creator')
    end
  end

答案 1 :(得分:1)

首先,您的数据库结构存在设计缺陷。我认为is_creator不应该在UserWorkout中。这是Workout

的责任

换句话说,Workout可以由用户创建,而User可以创建许多Workout,因此UserWorkout之间存在一对多关系{1}}

created_by_id中保留Workout并在其中添加关联。这将使许多事情变得更容易和更简单。

class Workout < ActiveRecord::Base

  has_many :user_workouts, inverse_of: :workout, dependent: :destroy
  has_many :participants, through: :user_workouts, source: :user

  belongs_to :creator ,  class_name: "User", foreign_key: "created_by_id"

end

并且不需要检查其独特性,因为它是Workout中的单个列

现在,每次您需要找到锻炼的创建者时,您都不需要复杂的查询。它是一个简单的belongs_to关联。一切都将由铁路照顾:)