3

5.0.0.beta2在 API 模式下使用 Rails。我有以下型号:

# == Schema Information
#
# Table name: teams
#
#  id             :integer          not null, primary key
#  competition_id :integer
#  name           :string
#  created_at     :datetime         not null
#  updated_at     :datetime         not null
#

class Team < ApplicationRecord

  belongs_to :competition, inverse_of: :teams, counter_cache: true

  has_many :user_teams, inverse_of: :team, dependent: :destroy
  has_many :users, inverse_of: :teams, through: :user_teams

  validates :competition, presence: true
  validates :name, presence: true, uniqueness: { scope: [:competition] }

end


# == Schema Information
#
# Table name: competitions
#
#  id           :integer          not null, primary key
#  classroom_id :integer
#  name         :string
#  start_at     :datetime
#  end_at       :datetime
#  created_at   :datetime         not null
#  updated_at   :datetime         not null
#

class Competition < ApplicationRecord

  belongs_to :classroom, counter_cache: true

  has_many :teams, inverse_of: :competition, dependent: :destroy

  validates :name, presence: true
  validates :start_at, timeliness: { type: :datetime }
  validates :end_at, timeliness: { after: :start_at, type: :datetime }

  scope :ordered, -> { order(:start_at) }

  accepts_nested_attributes_for :teams

end



# == Schema Information
#
# Table name: users
#
#  id         :integer          not null, primary key
#  name       :string
#  email      :string
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class User < ApplicationRecord

  has_many :user_teams, inverse_of: :user, dependent: :destroy
  has_many :teams, inverse_of: :users, through: :user_teams

  validates :name, presence: true
  validates :email, presence: true, uniqueness: true

  scope :ordered, -> { order(:name) }

end

# == Schema Information
#
# Table name: user_teams
#
#  id         :integer          not null, primary key
#  user_id    :integer
#  team_id    :integer
#  created_at :datetime         not null
#  updated_at :datetime         not null
#

class UserTeam < ApplicationRecord

  belongs_to :user, inverse_of: :user_teams
  belongs_to :team, inverse_of: :user_teams, counter_cache: :users_count

  validates :user, presence: true
  validates :team, presence: true, uniqueness: { scope: [:user] }

  validate :user_in_correct_classroom,
           :only_one_team_per_competition

  def user_in_correct_classroom
    if self.user.coursed_classrooms.include?(self.team.competition.classroom)
      return
    end
    self.errors
        .add(:user, "needs to be coursing in the competition's classroom")
  end

  def only_one_team_per_competition
    user =
      User.joins(:teams)
          .find_by(id: self.user_id,
                   teams: { competition_id: self.team.competition_id })
    if user
      self.errors.add(:user, 'can only participate in one team per competition')
    end
  end

end

当我尝试创建团队时:

#User with id=1 exists and is not present in any team
Competition.last.teams.create(name: "Rocket", user_ids: [1])

(和) 中validate定义的方法每个被调用 3 次。前两次调用成功,但在最后一次调用 for时,验证失败,因为 Rails 实际上已经在比赛中执行了团队和用户的插入。当然,这会回滚,并且团队实际上并未保存在数据库中。team.rbuser_in_correct_classroomonly_one_team_per_competitiononly_one_team_per_competition

我不明白为什么 Rails 会调用每个验证三次。我该如何解决这个问题,为什么会这样?

4

0 回答 0