Rails 使用 Unless 进行模型验证
Rails Model Validation using Unless
我有以下订阅 classes
的模型
create_table "subscriptions", force: true do |t|
t.integer "user_id"
t.integer "course_id"
t.datetime "date_subscription_start"
t.datetime "date_subscription_end"
t.string "subscription_type"
t.datetime "created_at"
t.datetime "updated_at"
end
我想这样做,以便用户能够再次订阅相同的 class,如果他们出于某种原因想要重新订阅的话。我的逻辑是,只有在 class / 用户组合的 date_subscription_end 日期在新创建时已经过去时,才可以注册 class。如果在创建时存在具有相同 user_id 和 course_id 且日期在未来 subscription_end 的订阅,则应该拒绝它,因为这意味着用户仍在学习该课程。
所以像这样:
validates :user_id,
uniqueness: {
scope: :course_id,
message: "User is already subscribed to this course"
},
unless: Proc.new { |a|
Subscription.where(user_id: a.user_id, course_id: a.course_id) &&
Subscription.where('date_subscription_end < ?', Time.now)
}
基本上 rails 必须遍历订阅表,找到所有具有相同主键的订阅并检查它们的 date_subscription_end 属性。我觉得我很接近但缺少一些基本的东西。
谢谢!
让
编辑:出于某种原因,post 顶部的 "Hello!" 问候语被删除
首先,Proc 看起来不正确,据我所知,Proc returns 是一个真实值,一旦用户订阅并且 some 用户 (不一定 a.user_id
) 订阅了 任何 课程(不一定 a.course_id
)
其次,unless 需要是一个 if 并且是唯一性验证的选项散列的一部分。
所以下面的代码应该可以工作:
validates :user_id,
uniqueness: {
scope: :course_id,
message: "User is already subscribed to this course",
if: Proc.new { |a|
Subscription.where(user_id: a.usr_id, course_id: a.course_id)
.where('date_subscription_end >= ?', Time.now).exists?
}
}
这样您只需访问数据库一次,并且您的代码不需要像 运行 .where(…)
那样实例化所有匹配的订阅
更新:
date_subscription_end
的条件应该是:'date_subscription_end >= ?', Time.now
我有以下订阅 classes
的模型create_table "subscriptions", force: true do |t|
t.integer "user_id"
t.integer "course_id"
t.datetime "date_subscription_start"
t.datetime "date_subscription_end"
t.string "subscription_type"
t.datetime "created_at"
t.datetime "updated_at"
end
我想这样做,以便用户能够再次订阅相同的 class,如果他们出于某种原因想要重新订阅的话。我的逻辑是,只有在 class / 用户组合的 date_subscription_end 日期在新创建时已经过去时,才可以注册 class。如果在创建时存在具有相同 user_id 和 course_id 且日期在未来 subscription_end 的订阅,则应该拒绝它,因为这意味着用户仍在学习该课程。
所以像这样:
validates :user_id,
uniqueness: {
scope: :course_id,
message: "User is already subscribed to this course"
},
unless: Proc.new { |a|
Subscription.where(user_id: a.user_id, course_id: a.course_id) &&
Subscription.where('date_subscription_end < ?', Time.now)
}
基本上 rails 必须遍历订阅表,找到所有具有相同主键的订阅并检查它们的 date_subscription_end 属性。我觉得我很接近但缺少一些基本的东西。
谢谢! 让
编辑:出于某种原因,post 顶部的 "Hello!" 问候语被删除
首先,Proc 看起来不正确,据我所知,Proc returns 是一个真实值,一旦用户订阅并且 some 用户 (不一定 a.user_id
) 订阅了 任何 课程(不一定 a.course_id
)
其次,unless 需要是一个 if 并且是唯一性验证的选项散列的一部分。
所以下面的代码应该可以工作:
validates :user_id,
uniqueness: {
scope: :course_id,
message: "User is already subscribed to this course",
if: Proc.new { |a|
Subscription.where(user_id: a.usr_id, course_id: a.course_id)
.where('date_subscription_end >= ?', Time.now).exists?
}
}
这样您只需访问数据库一次,并且您的代码不需要像 运行 .where(…)
更新:
date_subscription_end
的条件应该是:'date_subscription_end >= ?', Time.now