Home > Net >  rails custom validation method not being called
rails custom validation method not being called

Time:10-05

I created accept_waiver endpoint that allows user to sign a gym waiver. The next step is adding validation method :sign_only_one_waiver in the Gym model that validates user is just accepting only one waiver but the method is not being called.

I added on: :create so the validation will run when the relationship UserGymWaiver is created, which means that user has signed a waiver but still creates the relationship even if errors exist.

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

CodePudding user response:

The validation is in the Gym model, but you are creating a UserGymWaiver, so this code belongs in the UserGymWaiver model!

You could probably also solve it with a uniqueness validation and a scope, you can only allow one waiver per gym per user, you can find more info here:

https://guides.rubyonrails.org/active_record_validations.html#uniqueness

It could look something like this:

class UserGymWaiver < ApplicationRecord
  belongs_to :gym
  belongs_to :user

  validates :user, uniqueness: { scope: :gym,
    message: "you can only sign one waiver per gym" }
end
  • Related