【问题标题】:Many-to-Many Uniqueness Constraint Test Not Working多对多唯一性约束测试不起作用
【发布时间】:2012-01-08 21:40:11
【问题描述】:

我的 Rails 应用程序中的连接表是多对多关系。我在我的模型中使用 has_many :through 成语。为简单起见,让我们调用我的第一类 Student、我的第二类 Course 和连接表类 Enrollment(包含字段 student_id 和 course_id)。我想确保给定的学生最多与给定的课程关联一次(即 {student_id, course_id} 元组在注册表中应该是唯一的)。

所以我有一个迁移 a 来强制执行这种唯一性。

def change
  add_index :enrollments, [:student_id, :course_id], :unique => true
end

另外我的模型类是这样定义的:

class Student < ActiveRecord::Base
  has_many :enrollments  
  has_many :courses, :through => :enrollment

end

class Course < ActiveRecord::Base
  has_many :enrollments
  has_many :students, :through => :enrollment

end

class Enrollment < ActiveRecord::Base
  belongs_to :student
  belongs_to :course

  validates :student,    :presence => true
  validates :course,     :presence => true
  validates :student_id, :uniqueness => {:scope => :course_id}

end

在 Rails 控制台中,我可以执行以下操作:

student = Student.first
course = Course.first
student.courses << course
#... succeeds
student.courses << course
#... appropriately fails and raises an ActiveRecord::RecordInvalid exception

在我的 RSpec 测试中,我做了完全相同的事情,以下代码也没有例外:

@student.courses << @course
expect { @student.courses << @course }.to raise_error(ActiveRecord::RecordInvalid)

所以我的测试失败并报告:

expected ActiveRecord::RecordInvalid but nothing was raised

这里发生了什么?我可能做错了什么?我该如何解决?

【问题讨论】:

    标签: validation ruby-on-rails-3.1 many-to-many rspec2 unique


    【解决方案1】:

    Rails 使用模型级别验证,如果您想要严格检查唯一性,您需要使用数据库级别 - 例如外键。但在这种情况下,您需要从数据库连接器中捕获异常。 这很奇怪,因为在我的代码(与您的代码非常相似)中,对唯一性的验证会引发异常。

    【讨论】:

      【解决方案2】:

      这里可能会发生几件事:

      1. @courses 在不同用途之间发生了变化。
      2. @student 在使用之间发生了变化。

      通过使用let,您将保护这些值不会在期望之间发生变化。

      let(:course) { Course.first }
      let(:student) { Student.first }
      subject{ student.courses << course << course }
      it { should raise_error(ActiveRecord::RecordInvalid) }
      

      或者,您的代码可能有问题:)

      【讨论】:

        猜你喜欢
        • 2017-03-26
        • 1970-01-01
        • 2022-11-11
        • 2015-08-04
        • 1970-01-01
        • 2010-12-22
        • 2013-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多