Creé un punto final accept_waiver que permite al usuario firmar una exención de gimnasio. El siguiente paso es agregar el método de validación :sign_only_one_waiver en el modelo Gym que valida que el usuario solo acepta una exención, pero no se llama al método.
Agregué on: :create para que la validación se ejecute cuando se cree la relación UserGymWaiver, lo que significa que el usuario ha firmado una renuncia pero aún crea la relación incluso si existen errores.
app/modelos/gimnasio.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 endaplicación/controladores/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]) endLa validación está en el modelo Gym , pero está creando un UserGymWaiver , ¡así que este código pertenece al modelo UserGymWaiver !
Probablemente también podría resolverlo con una validación de unicidad y un alcance, solo puede permitir una exención por gimnasio por usuario, puede encontrar más información aquí:
https://guides.rubyonrails.org/active_record_validations.html#uniqueness
Podría verse algo como esto:
class UserGymWaiver < ApplicationRecord belongs_to :gym belongs_to :user validates :user, uniqueness: { scope: :gym, message: "you can only sign one waiver per gym" } end