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