All threads / DRY Validations for Similar Models

Ask A Question

Notifications

You’re not receiving notifications from this thread.

DRY Validations for Similar Models

Sillico asked in Rails

In my app I have restaurants which have a name, address, state, zipcode, country, and some other stuff. These restaurants have many locations, and each location belongs to a restaurant. The locations also hold a name, address, state, zipcode, and country. I was wondering if there is a clean way of writing validations in their model files without having to repeat myself in each model file? Can validations go into a function?

Thanks.

Definitely! You can probably do this cleanest by creating a Concern and putting the validations in there, then including the concern in both models. That's exactly the purpose they're designed for, so they should do exactly what you want.

Just to provide an alternative solution - If you're still early in the development cycle and haven't gone to production yet, you could also create a contact model that stores all the address info, then you'd only have one model to manage validations:

#models/restraunt.rb
has_one :contact, as: :contactable, dependent: :destroy

#models/location.rb
has_one :contact, as: :contactable, dependent: :destroy

#models/contact.rb
belongs_to :contactable, polymorphic: true

then your migration could be something like:

class CreateContacts < ActiveRecord::Migration
  def change
    create_table :contacts do |t|
      t.string :line_1
      t.string :line_2
      t.string :city
      t.integer :state, :default => 0
      t.string :zip
      t.string :email
      t.string :phone
      t.decimal :lat, :precision => 10, :scale => 6, :default => 0
      t.decimal :lng, :precision => 10, :scale => 6, :default => 0
      t.references :contactable, polymorphic: true, index: true

      t.timestamps null: false
    end
  end
end

Thanks to both of you for the solutions! That worked well.

In addition, here is the code I used for the solution Chris suggested, for anyone interested.

# /models/concerns/location_validations.rb
module LocationValidations
    extend ActiveSupport::Concern

    included do
        validates :name,    presence: true
        validates :address, presence: true
        validates :state,   presence: true
        validates :zipcode, presence: true
        validates :country, presence: true
    end
end
# models/restaurant.rb
class Restaurant < ApplicationRecord
    has_many :branches
    has_and_belongs_to_many :users
    validates :phone, presence: true
    validates :email, presence: true
    include LocationValidations
end
# models/branch.rb
class Branch < ApplicationRecord
    belongs_to :restaurant
    validates :restaurant_id, presence: true
    include LocationValidations
end
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 33,399+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2020 GoRails, LLC. All rights reserved.