Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?

I was looking model generic custom validations. I ended up with something that I thought could be shared, including generic tests.

First, set up the concern app/models/concern/my_concern.rb. Please note that we don't define the validate_my_field into a ClassMethods module.

module MyConcern
  extend ActiveSupport::Concern

  included do
    validate :my_field, :validate_my_field
  end

private

  def validate_my_field
    ...
  end

end

Include concern into your model app/models/my_model.rb

class MyModel < ActiveRecord::Base
  include MyConcern
end

Load concerns shared examples in spec/support/rails_helper:

...
Dir[Rails.root.join('spec/concerns/**/*.rb')].each { |f| require f }
...

Create concern shared examples spec/concerns/models/my_field_concern_spec.rb:

RSpec.shared_examples_for 'my_field_concern' do
  let(:model) { described_class } # the class that includes the concern

  it 'has a valid my_field' do
    instance = build(model.to_s.underscore.to_sym, my_field: …)
    expect(instance).not_to be_valid
    …
  end
end

Then finally call shared examples into your model spec spec/models/my_model_spec.rb:

require 'rails_helper'

RSpec.describe MyModel do
  include_examples 'my_field_concern'

  it_behaves_like 'my_field_concern'
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment