Skip to content

Instantly share code, notes, and snippets.

@feymartynov
Created November 7, 2016 10:22
Show Gist options
  • Save feymartynov/668f3bdcfcdff1f63f4970aa3ea5a2ac to your computer and use it in GitHub Desktop.
Save feymartynov/668f3bdcfcdff1f63f4970aa3ea5a2ac to your computer and use it in GitHub Desktop.
rom aggregate with join table
require 'pp'
require 'pry'
require 'rom'
require 'rom-sql'
require 'rom-repository'
require 'dry-struct'
rom = ROM.container(:sql, 'sqlite::memory') do |conf|
conf.default.create_table(:movies) do
primary_key :id
column :title, String, null: false
end
conf.default.create_table(:actors) do
primary_key :id
column :name, String, null: false
end
conf.default.create_table(:roles) do
primary_key :id
foreign_key :actor_id, :actors, null: false
foreign_key :movie_id, :movies, null: false
column :name, String, null: false
end
conf.relation(:actors) do
schema(infer: true) do
associations do
has_many :roles
end
end
view(:for_movies, [:actor_id, :actor_name, :name, :movie_id]) do |movies|
prefix(:actor)
.qualified
.select_append(:roles__name, :roles__movie_id)
.inner_join(:roles, roles__actor_id: :actors__id)
.where(roles__movie_id: movies.pluck(:id))
end
end
conf.relation(:roles) do
schema(infer: true) do
associations do
belongs_to :movie
belongs_to :actor
end
end
end
conf.relation(:movies) do
schema(infer: true) do
associations do
has_many :roles
has_many :actors, through: :roles
end
end
end
end
DB = rom.gateways[:default].connection
movie_id = DB[:movies].insert(title: "Star Wars")
actor_id = DB[:actors].insert(name: "Peter Mayhew")
DB[:roles].insert(movie_id: movie_id, actor_id: actor_id, name: "Chewbacca")
class MovieRepo < ROM::Repository[:movies]
relations :actors
def with_casts
movies.combine_children(many: { casts: actors.for_movies })
end
end
pp MovieRepo.new(rom).with_casts.one
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment