Skip to content

Instantly share code, notes, and snippets.

@mbrehin
Last active March 17, 2017 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mbrehin/828d3eb11393e1cfe24339e185e5dddf to your computer and use it in GitHub Desktop.
Save mbrehin/828d3eb11393e1cfe24339e185e5dddf to your computer and use it in GitHub Desktop.

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