Skip to content

Instantly share code, notes, and snippets.

@Kukunin
Last active February 26, 2017 10:48
Show Gist options
  • Save Kukunin/86d4b15fe57dd61ef8d379a9f306f3cf to your computer and use it in GitHub Desktop.
Save Kukunin/86d4b15fe57dd61ef8d379a9f306f3cf to your computer and use it in GitHub Desktop.
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'
gem 'rom-sql'
gem 'rom-repository'
gem 'sqlite3'
gem 'rspec'
gem 'pry'
end
require 'rspec/autorun'
class User < Dry::Struct
attribute :name, Dry::Types['strict.string']
end
class Post < Dry::Struct
attribute :title, Dry::Types['strict.string']
attribute :user, User
end
class UsersMapper < ROM::Mapper
relation :users
register_as :entity
attribute :name, from: :nname
model User
end
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
column :nname, String, null: false
end
config.default.create_table(:posts) do
primary_key :id
foreign_key :user_id, :users, null: false
column :title, String, null: false
end
config.relation(:users) do
schema(infer: true)
view :as_entity do
schema { rename(nname: :name) }
relation { as(:entity) }
end
end
config.register_mapper(UsersMapper)
end
end
let(:repo) do
Class.new(ROM::Repository[:posts]) do
relations :users
def all
posts.combine_parents(one: users.as_entity).as(Post).to_a
end
end.new(rom)
end
before { create_post(title: 'post_title', user_name: 'Sergiy') }
it 'fetches 1 record' do
expect(repo.all.count).to eq 1
end
it 'builds User' do
expect(repo.users.as(:entity).first).to be_a(User)
end
let(:first) { repo.all.first }
it 'builds Post struct' do
expect(first).to be_a(Post)
expect(first.title).to eq 'post_title'
expect(first.user.name).to eq 'Sergiy'
end
def create_post(attrs)
user_id = rom.relations[:users].insert(nname: attrs.fetch(:user_name))
rom.relations[:posts].insert(title: attrs.fetch(:title), user_id: user_id)
end
end
@Kukunin
Copy link
Author

Kukunin commented Feb 10, 2017

Let's assume as fact, that we need to map record from users table in order to create User entity. For simplicity, we just need to rename :nname into :name. And we want to combine posts relation with its parent users.

Test fails, because mapping isn't called, while repo.users.as(:entity) maps users to User struct without problems

@Kukunin
Copy link
Author

Kukunin commented Feb 26, 2017

3rd revision works fine

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