Skip to content

Instantly share code, notes, and snippets.

@anicholson
Last active June 24, 2016 02:01
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 anicholson/ba2cfe4fbb469b1aa01f7597056e7108 to your computer and use it in GitHub Desktop.
Save anicholson/ba2cfe4fbb469b1aa01f7597056e7108 to your computer and use it in GitHub Desktop.
Breaking Trailblazer Contract

To reproduce:

  1. bundle install
  2. bundle exec rake test_case

Expected: record is updated Actual: contract fails, claims keys are missing.

# A sample Gemfile
source "https://rubygems.org"
gem 'reform', '~> 2.2'
gem 'trailblazer'
gem 'dry-validation'
gem 'dry-types'
gem 'sqlite3'
gem 'activerecord', '< 5'
gem 'rake'
GEM
remote: https://rubygems.org/
specs:
activemodel (4.2.6)
activesupport (= 4.2.6)
builder (~> 3.1)
activerecord (4.2.6)
activemodel (= 4.2.6)
activesupport (= 4.2.6)
arel (~> 6.0)
activesupport (4.2.6)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
arel (6.0.3)
builder (3.2.2)
concurrent-ruby (1.0.2)
declarative (0.0.7)
uber (>= 0.0.15)
disposable (0.3.0)
declarative (~> 0.0.6)
representable (>= 2.4.0, <= 3.1.0)
uber
dry-configurable (0.1.6)
concurrent-ruby (~> 1.0)
dry-container (0.3.4)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1, >= 0.1.3)
dry-equalizer (0.2.0)
dry-logic (0.2.3)
dry-container (~> 0.2, >= 0.2.6)
dry-equalizer (~> 0.2)
dry-monads (0.0.1)
dry-types (0.7.2)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1)
dry-container (~> 0.3)
dry-equalizer (~> 0.2)
dry-logic (~> 0.2, >= 0.2.3)
dry-monads (>= 0.0.1)
inflecto (~> 0.0.0, >= 0.0.2)
dry-validation (0.7.4)
concurrent-ruby (~> 1.0)
dry-configurable (~> 0.1, >= 0.1.3)
dry-container (~> 0.2, >= 0.2.8)
dry-equalizer (~> 0.2)
dry-logic (~> 0.2, >= 0.2.2)
dry-types (~> 0.6, >= 0.6.0)
i18n (0.7.0)
inflecto (0.0.2)
json (1.8.3)
minitest (5.9.0)
rake (11.1.2)
reform (2.2.1)
disposable (>= 0.3.0, < 0.4.0)
representable (>= 2.4.0, < 3.1.0)
uber (~> 0.0.11)
representable (3.0.0)
declarative (~> 0.0.5)
uber (~> 0.0.15)
sqlite3 (1.3.11)
thread_safe (0.3.5)
trailblazer (1.1.1)
declarative
reform (>= 2.0.0, < 3.0.0)
uber (>= 0.0.15)
tzinfo (1.2.2)
thread_safe (~> 0.1)
uber (0.0.15)
PLATFORMS
ruby
DEPENDENCIES
activerecord (< 5)
dry-types
dry-validation
rake
reform (~> 2.2)
sqlite3
trailblazer
BUNDLED WITH
1.11.2
require 'bundler/setup'
Bundler.require(:default)
require 'dry/validation'
require 'dry/types'
require 'trailblazer'
require 'reform/form/dry'
require 'active_record'
require 'pp'
class Employee < ActiveRecord::Base
class Contract < Reform::Form
feature Reform::Form::Dry
property :core_data_name
property :core_data_employee_id
validation :default do
key(:core_data_name).required{ empty? | filled? }
key(:core_data_employee_id).required { empty? | filled? }
end
end
class Update < ::Trailblazer::Operation
class NoSuchEmployee < Exception; end
contract ::Employee::Contract
def model!(params)
org_id = params[:organisation_id] || :missing
employee_id = params[:employee].try(:[], :core_data_employee_id) || :missing
employee = Employee.find_by_organisation_id_and_core_data_employee_id(org_id, employee_id)
unless employee
raise NoSuchEmployee
end
employee
end
def process(params)
validate(params[:employee]) do |updated_employee|
updated_employee.save
end
end
end
end
task :connect do
ActiveRecord::Migration.verbose = false
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
ActiveRecord::Schema.define(version: 1) do
create_table "employees", force: :cascade do |t|
t.string "core_data_name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "core_data_employee_id"
t.string "organisation_id", null: false
end
end
end
task :test_case => [:connect] do
Employee.create!(organisation_id: 1, core_data_employee_id: 1, core_data_name: 'Fred')
puts "BEFORE:"
pp Employee.last.attributes
params = {
organisation_id: 1,
employee: {
core_data_name: 'Fred Prime',
core_data_employee_id: 1
}
}.with_indifferent_access
Employee::Update.(params)
puts "AFTER:"
pp Employee.last.attributes
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment