Search code examples
ruby-on-rails-4.2custom-validators

Refactoring repeated custom validation in Rails


I have a custom validation which is repeated multiple models. Is there a way to refactor it and make it dry?

class Channel < ActiveRecord::Base

  belongs_to :bmc
  has_and_belongs_to_many :customer_segments

  validates :name, presence: true
  validate :require_at_least_one_customer_segment

  private

  def require_at_least_one_customer_segment
    if customer_segments.count == 0
      errors.add_to_base "Please select at least one customer segment"
    end
  end

end



class CostStructure < ActiveRecord::Base

  belongs_to :bmc
  has_and_belongs_to_many :customer_segments

  validates :name, presence: true
  validate :require_at_least_one_customer_segment

  private

  def require_at_least_one_customer_segment
    if customer_segments.count == 0
      errors.add_to_base "Please select at least one customer segment"
    end
  end
end

 class CustomerSegment < ActiveRecord::Base
   has_and_belongs_to_many :channels
   has_and_belongs_to_many :cost_structures
 end

Any reference link also much appreciated.Thanks!!


Solution

  • Try using concerns:

    app/models/concerns/shared_validations.rb

    module SharedValidations
      extend ActiveSupport::Concern
      include ActiveModel::Validations
    
      included do 
        belongs_to :bmc
        has_and_belongs_to_many :customer_segments
    
        validates :name, presence: true
        validate :require_at_least_one_customer_segment
      end
    end
    

    then in your classes:

    class CostStructure < ActiveRecord::Base
        include Validateable
    end