saGii
saGii

Reputation: 477

rails 3 validations uniqueness on attributes of an association

i have a model called Fund and a model called Company .. where fund belongs_to a company.

i have this validation in my Fund table:

validates :name, presence: true, uniqueness: true

This works both on server side and client side using client_side_validations. But i want my fund names to be unique across both fund.name values and fund.company.name values. And i want to do it in a way it would work with client_side_validations too.

Suggestions?

Upvotes: 0

Views: 201

Answers (1)

saGii
saGii

Reputation: 477

Ended up creating a very specific validator and adding it to client-side-validation. Here'z the breakdown

In models/fund.rb

validates_fund_name_not_company_name :name

new file in config/initializers/validators .. called fund_name_not_company_name_validator.rb

class FundNameNotCompanyNameValidator < ActiveModel::EachValidator
  def validate_each(record, attr_name, value)
    if ::Company.exists?(name: value)
      record.errors.add(attr_name, :fund_name_not_company_name, options.merge(:value => value))
    end
  end
end

# This allows us to assign the validator in the model
module ActiveModel::Validations::HelperMethods
  def validates_fund_name_not_company_name(*attr_names)
    validates_with FundNameNotCompanyNameValidator, _merge_attributes(attr_names)
  end
end

module ClientSideValidations::Middleware
  class FundNameNotCompanyName < ClientSideValidations::Middleware::Base
    def response
      if ::Company.exists?(name: request.params[:name])
        self.status = 404
      else
        self.status = 200
      end
      super
    end
  end
end

then in app/assets/javascripts/rails.validations.custom.js clientSideValidations.validators.remote['fund_name_not_company_name'] = function(element, options) { if ($.ajax({ url: '/validators/fund_name_not_company_name', data: { name: element.val() }, // async must be false async: false }).status == 404) { return options.message; } }

This helped a great deal

Upvotes: 1

Related Questions