Skip to content

Instantly share code, notes, and snippets.

@Kukunin
Last active February 9, 2017 10:47
Show Gist options
  • Save Kukunin/ac59b987bbfc9b7d6055caa9f2c02e32 to your computer and use it in GitHub Desktop.
Save Kukunin/ac59b987bbfc9b7d6055caa9f2c02e32 to your computer and use it in GitHub Desktop.
ROM value object persistence
begin
require 'bundler/inline'
rescue LoadError => e
$stderr.puts 'Bundler version 1.10 or later is required.'
raise e
end
gemfile(true) do
source 'https://rubygems.org'
gem 'rom', git: 'https://github.com/rom-rb/rom.git'
gem 'rom-sql', git: 'https://github.com/rom-rb/rom-sql.git'
gem 'rom-repository', git: 'https://github.com/rom-rb/rom-repository.git'
gem 'sqlite3'
gem 'rspec'
end
require 'rspec/autorun'
describe ROM::Repository do
let(:rom) { ROM.container(configuration) }
let(:configuration) do
ROM::Configuration.new(:sql, 'sqlite::memory').tap do |config|
config.default.create_table(:users) do
primary_key :id
foreign_key :address_id, :addresses, null: false
end
config.default.create_table(:addresses) do
primary_key :id
column :street_name, String, null: false
column :city, String, null: false
end
end
end
let(:repo) do
Class.new(ROM::Repository[:users]) do
relations :addresses
end.new(rom)
end
describe 'creation' do
let(:user_struct) do
Address = Class.new(Dry::Struct) do
attribute :street_name, Dry::Types['strict.string']
attribute :city, Dry::Types['strict.string']
end
User = Class.new(Dry::Struct) do
attribute :id, Dry::Types['strict.int'].optional
attribute :address, Address
end
end
let(:user) do
user_struct[
id: nil,
address: {
street_name: '123 Street',
city: 'Los Angeles'
}
]
end
let(:rom) do
configuration.relation(:users) do
schema(infer: true) do
associations do
belongs_to :address
end
end
end
ROM.container(configuration)
end
it 'has valid aggregation' do
create_user(street_name: '123 Hollywood St', city: 'Los Angeles')
create_user(street_name: '7th Avenue', city: 'New York')
combined_relation = repo.aggregate(:address)
expect(combined_relation.count).to eq 2
expect(combined_relation.limit(1).one.to_h).to include(
address: hash_including(street_name: '123 Hollywood St', city: 'Los Angeles')
)
end
it 'saves it' do
command = repo.command(:create, repo.aggregate(:address))
expect { command.call(user.to_h) }.to change(repo.users, :count).by(1)
# ROM::SQL::NotNullConstraintError:
# SQLite3::ConstraintException: NOT NULL constraint failed: users.address_id
end
end
def create_user(address)
address_id = rom.relations[:addresses].insert(address)
rom.relations[:users].insert(address_id: address_id)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment