我正在使用Rails编写Web应用程序,其中一部分包括让用户能够为事物留下评论。我想在review
模型中进行验证,以确保一个用户不能对同一项目进行多次审核,因此我写了这个:
class NoDuplicateReviewValidator < ActiveModel::Validator
def validate(record)
dup_reviews = Review.where({user_id: record.user,
work_id: record.work})
unless dup_reviews.length < 1
record.errors[:duplicate] << "No duplicate reviews!"
end
end
end
此验证器具有所需的行为,即它保证用户无法两次查看作品。然而,它具有不期望的副作用,即用户无法更新他/她离开的现有评论。我使用的是一个非常简单的
def update
@review.update(review_params)
respond_with(@work)
end
在评论控制器中。如何更改验证程序或更新方法以防止重复审核但允许更新?
我对Rails和网站开发都很陌生,所以我确定我在这里做了一些傻瓜。我没有使用其中一个内置unique
验证器,因为唯一的是user
/ work
对;不同作品的同一用户可以进行多次审核,不同用户可以对同一作品进行多次审核。
答案 0 :(得分:2)
您可以对多个属性使用validates_uniqueness_of
,如下所示:
validates_uniqueness_of :user_id, :scope => :work_id
然后,不允许用户查看已经审核过的作品。
答案 1 :(得分:0)
@Sharvy Ahmed的回答绝对是最好的,只要情况足够简单– OP的情况似乎就是其中之一。
但是,如果条件更复杂,则可能需要/希望编写自定义验证。为此,这里有一个示例(已在Rails 6.0中选中)。
class NoDuplicateReviewValidator < ActiveModel::Validator
def validate(record)
dup_reviews = Review.where(user_id: record.user,
work_id: record.work)
dup_reviews = dup_reviews.where.not(id: record.id) unless record.new_record?
if dup_reviews.count > 0
record.errors[:duplicate] << "No duplicate reviews!"
end
end
end
这个想法是
where
检索的所有相关数据库记录来判断唯一性。在示例中,new_record?
用于检出,但实际上是多余的(因为nil id
与记录不匹配)。record
的DB行。否则,更新将始终无法通过验证。count
方法效率更高。