Skip to content

Instantly share code, notes, and snippets.

@ethnt
Created March 4, 2019 11:50
Show Gist options
  • Save ethnt/b4989bf5945f42d9589491f4b6eab2d3 to your computer and use it in GitHub Desktop.
Save ethnt/b4989bf5945f42d9589491f4b6eab2d3 to your computer and use it in GitHub Desktop.
ROM self-referential associations with views
# frozen_string_literal: true
require 'types'
module Persistence
module Relations
# Relation for the +regions+ table.
class Regions < ROM::Relation[:sql]
schema(:regions) do
attribute :id, Types::Int
attribute :country_id, Types::ForeignKey(:countries)
attribute :region_id, Types::ForeignKey(:regions)
primary_key :id
associations do
belongs_to :country
belongs_to :region, foreign_key: :region_id
has_many :regions, view: :children
end
end
# Find a specific region.
#
# @param id [Integer]
# @return [Country]
def find(id)
by_pk(id).one!
end
# Helps to build the aggregate/combine functions from +Graham::Repositories::CountriesRepository+.
#
# @example
# countries_repository.aggregate(:regions).one # => Graham::Entities::Country
#
# @param assoc [ROM::SQL::Associations::OneToMany] The association. We use this to build the query.
# @param countries [Persistence::Relations::Countries] The countries we're querying for.
# @return [Persistence::Relations::Regions] A relation with the correct query.
def children(assoc, countries)
assoc.target.where(region_id: nil, country_id: countries.pluck(:id))
end
struct_namespace ::Graham::Entities
auto_struct true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment