【问题标题】:How to prevent multiple entries of the exactly same parameters?如何防止完全相同参数的多个条目?
【发布时间】:2019-12-27 10:57:28
【问题描述】:

我有一个 Rails 应用程序,学生可以在其中通过注册来注册课程。这是一个 has_many_through 关联。

但是,我有一个学生可以多次注册同一课程的问题。

#<StudentEnrollment course_code: "GST311", student_id: 1, created_at: "2019-11-20 17:52:22", updated_at: "2019-11-20 17:52:22">, 
#<StudentEnrollment course_code: "GST311", student_id: 1, created_at: "2019-11-20 17:53:14", updated_at: "2019-11-20 17:53:14">, 
#<StudentEnrollment course_code: "GST311", student_id: 1, created_at: "2019-11-20 18:00:33", updated_at: "2019-11-20 18:00:33">

是否有适当的方法来检查是否存在完全相同的注册并防止它被重新创建?

【问题讨论】:

  • 是的,在[:student_id, :course_code] 上设置唯一索引。然后数据库为您完成所有工作。
  • 你的意思是像模型中的验证?
  • 未验证。指数。使用add_index :student_enrollments, [:student_id, :course_code], unique: true 进行迁移。验证是 Rails 在尝试保存之前进行检查。唯一索引使数据库绝对拒绝索引列重复的记录。你可以绕过前者,但不能绕过后者。
  • 它通过了这个错误SQLite3::ConstraintException: UNIQUE constraint failed: student_enrollments.student_id, student_enrollments.course_code
  • 应该如此。如果您在迁移过程中遇到错误,则表示您的数据库已经不合规。在再次尝试迁移之前擦除它(或至少删除有问题的记录)。如果您在尝试插入记录时遇到错误,这就是应该发生的情况:拯救它并向用户显示自定义错误,或者当用户出现这种情况时执行您想做的任何事情。

标签: ruby-on-rails


【解决方案1】:

您可以在此处使用范围唯一性验证。唯一性验证允许我们基于两个或多个属性的组合来指定唯一性。因此,根据作用域验证,course_code + student_id 组合只能存在一次。可以写成:

class StudentEnrollment <ApplicationRecord
  validates :student_id, uniqueness: { scope: :course_id }
end

这将确保学生-课程组合只能在数据库中输入一次。

您可以在此处查看唯一性验证指南:https://guides.rubyonrails.org/active_record_validations.html#uniqueness。这处理了应用程序级别的唯一性。

此外,如指南中所述,

如果您希望使用 :scope 选项创建数据库约束以防止可能违反唯一性验证,则必须在数据库中的两个列上创建唯一索引。

【讨论】:

    猜你喜欢
    • 2016-12-12
    • 2011-07-04
    • 2018-07-14
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    • 2019-09-09
    • 2011-12-27
    • 2011-04-29
    相关资源
    最近更新 更多