rails 自定义验证方法未被调用
rails custom validation method not being called
我创建了 accept_waiver
允许用户签署健身房弃权书的端点。下一步是在 Gym 模型中添加验证方法 :sign_only_one_waiver
以验证用户仅接受一次豁免但未调用该方法。
我添加了 on: :create
,因此在创建关系 UserGymWaiver 时验证将 运行,这意味着用户已签署弃权书但即使存在错误仍会创建关系。
app/models/gym.rb
class Gym < ApplicationRecord
include PgSearch::Model
validate :sign_only_one_waiver, on: :create
enum tier: {
standard: 'standard',
premium: 'premium'
}
has_many :gym_amenities, dependent: :destroy
has_many :amenities, through: :gym_amenities
reverse_geocoded_by :latitude, :longitude
pg_search_scope :search,
against: [
:name,
:tier
],
using: {
tsearch: {prefix: true}
}
def sign_only_one_waiver
user_waiver_collection = UserGymWaiver.where(gym_id: self.gym_id)
errors.add(:gym, "you can only sign one waiver") if user_waiver_collection.count > 1
end
app/controllers/api/v1/gyms_controller.rb
class Api::V1::GymsController < ApplicationController
before_action :load_gym, only: %i[accept_waiver]
def accept_waiver
gym_waiver = GymWaiver.find_by(gym_id: @gym.id)
waiver_signed_by_user = UserGymWaiver.create!(user_id: current_user.id,
gym_id: gym_waiver.gym_id)
render json: UserGymWaiverBlueprint.render(waiver_signed_by_user, root: :data)
end
private
def load_gym
@gym = Gym.find(params[:id])
end
验证在 Gym
模型中,但您正在创建 UserGymWaiver
,因此此代码属于 UserGymWaiver
模型!
你也可以通过唯一性验证和范围来解决它,你只能允许每个用户每个健身房一次豁免,你可以在这里找到更多信息:
https://guides.rubyonrails.org/active_record_validations.html#uniqueness
它可能看起来像这样:
class UserGymWaiver < ApplicationRecord
belongs_to :gym
belongs_to :user
validates :user, uniqueness: { scope: :gym,
message: "you can only sign one waiver per gym" }
end
我创建了 accept_waiver
允许用户签署健身房弃权书的端点。下一步是在 Gym 模型中添加验证方法 :sign_only_one_waiver
以验证用户仅接受一次豁免但未调用该方法。
我添加了 on: :create
,因此在创建关系 UserGymWaiver 时验证将 运行,这意味着用户已签署弃权书但即使存在错误仍会创建关系。
app/models/gym.rb
class Gym < ApplicationRecord
include PgSearch::Model
validate :sign_only_one_waiver, on: :create
enum tier: {
standard: 'standard',
premium: 'premium'
}
has_many :gym_amenities, dependent: :destroy
has_many :amenities, through: :gym_amenities
reverse_geocoded_by :latitude, :longitude
pg_search_scope :search,
against: [
:name,
:tier
],
using: {
tsearch: {prefix: true}
}
def sign_only_one_waiver
user_waiver_collection = UserGymWaiver.where(gym_id: self.gym_id)
errors.add(:gym, "you can only sign one waiver") if user_waiver_collection.count > 1
end
app/controllers/api/v1/gyms_controller.rb
class Api::V1::GymsController < ApplicationController
before_action :load_gym, only: %i[accept_waiver]
def accept_waiver
gym_waiver = GymWaiver.find_by(gym_id: @gym.id)
waiver_signed_by_user = UserGymWaiver.create!(user_id: current_user.id,
gym_id: gym_waiver.gym_id)
render json: UserGymWaiverBlueprint.render(waiver_signed_by_user, root: :data)
end
private
def load_gym
@gym = Gym.find(params[:id])
end
验证在 Gym
模型中,但您正在创建 UserGymWaiver
,因此此代码属于 UserGymWaiver
模型!
你也可以通过唯一性验证和范围来解决它,你只能允许每个用户每个健身房一次豁免,你可以在这里找到更多信息:
https://guides.rubyonrails.org/active_record_validations.html#uniqueness
它可能看起来像这样:
class UserGymWaiver < ApplicationRecord
belongs_to :gym
belongs_to :user
validates :user, uniqueness: { scope: :gym,
message: "you can only sign one waiver per gym" }
end