【问题标题】:Mongoid saving documents despite invalid custom validation尽管自定义验证无效,但 Mongoid 保存文档
【发布时间】:2012-09-21 16:26:20
【问题描述】:

我不确定这是 Mongoid 还是标准 Rails 验证器的问题,但无效的文档仍在保存到数据库中。

我的模型设置为:

class League
  include Mongoid::Document

  has_many :teams

  validate do
    if teams.size > 12
      errors.add(:teams, 'too many teams')
    end
  end
end

class Team
  include Mongoid::Document

  belongs_to :league
end

我希望通过以下测试,但它没有。不是我的自定义验证阻止超过 12 支球队被添加到联赛中,而是联赛得到了 13 支球队的保存。

# Factory for a League.
FactoryGirl.define do
  factory :league do
  name "Test League"

  factory :league_with_teams do
    ignore do
      teams_count 5
    end

    after(:create) do |league, evaluator|
      FactoryGirl.create_list(:team, 
                              evaluator.teams_count, 
                              league: league)
    end
  end
end

describe League do
  it "should not allow more than 12 teams" do
    league = FactoryGirl.create(:league_with_teams, teams_count: 12)
    league.teams << FactoryGirl.create(:team)
    league.should_not be_valid # passes
    League.find(league.id).teams.size.should eq(12) # fails
  end
end

有趣的是,如果我在测试中更改添加第 13 个团队以使用构建而不是创建的行league.teams &lt;&lt; FactoryGirl.build(:team),则测试通过。然而,这不是一个解决方案,因为我想保证一个联赛不能超过 12 支球队,无论添加的球队是新的还是已经在数据库中。

有没有办法保证这一点?

编辑

向团队模型添加验证器,就像我在下面所做的那样,似乎也不起作用。

class Team
  include Mongoid::Document

  belongs_to :league

  validate do |team|
    if league.teams.size > 12
      errors.add :base, "cannot have more than 12 teams in a league"
    end
  end
end

我认为问题与&lt;&lt;push 是原子操作有关,因此它们会跳过回调和验证。话虽这么说,这一定是一个相当常见的用例,不是吗?那么其他人如何验证被引用的文档数量呢?

【问题讨论】:

  • 验证应该在团队中
  • 这似乎不能解决问题。
  • 你到底做了什么?
  • 好的,知道了。将league.teams &lt;&lt; FactoryGirl.create(:team) 替换为league.teams.create(FactoryGirl.attributes_for(:team))
  • 如果我想将已经存在的团队添加到联赛中怎么办?验证不会发生,我可能会超过 12 个团队。

标签: ruby-on-rails ruby validation associations mongoid


【解决方案1】:

我认为问题不在于&lt;&lt;push 方法,因为它们都应该触发模型的验证。

尝试使用:

league.teams << FactoryGirl.create(:team, league: league)

【讨论】:

  • 我最终不得不使用 mongoid 主分支的 after_add 和 before_add 回调来让它工作。原子推送方法不执行验证。
猜你喜欢
  • 2018-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多