【rails】关联的唯一性约束

rails中,通过has_many through建立的两个模型之间的关联是以模型存在的。
在实际使用中,我们往往会遇到需要使关联唯一的情况,例如用户之间的关注关系,你一般不会想要在关联表中存放两个相同的记录。
这时,在应用级(即model文件)中可以验证uniqueness,在scope选项中填入要关联的元素,即可实现在多个属性上的唯一性验证。
这里是以学生选课为例子,在我们的例子中,假设学生与课程之间的选课关系唯一(实际上可能还有重修,我们先不考虑)
user表示学生,course代表课程,那么我们可以在courses_users.rb中加入以下验证

validates :user_id, uniqueness: { scope: :course_id }

当然,course_id和user_id的位置可以对调。

但是这只是在应用级进行约束,只有用户进行更新数据时才会去验证。而当数据库中原本就有数据时,该验证将不起作用。
更严重的是,在并发访问时,该约束并不保证一致性。即如果两个请求都添加同一选课关系时(虽然在该例中不太可能,但我们仍要考虑),由于并行执行,就可能出现出现两个都保存成功。
这是因为在并发执行时,该表相当于临界资源,验证时两个请求可能同时去查询该表,此时表中没有重复数据,于是两者都发现满足约束,就插入了两个相同的数据。
解决的方法是在表上建立唯一性约束

一个比较好的解决方法是添加带唯一性约束的多值索引
在数据库迁移中:

add_index :course_user_associations,
              [:course_id, :user_id], unique: true, name: :unique_index

这里指定了index的name,这是因为默认的命名很容易超出字数限制。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值