Class: ROM::Repository

Inherits:
Object
  • Object
show all
Extended by:
ClassInterface
Defined in:
lib/rom/repository.rb,
lib/rom/repository/root.rb,
lib/rom/repository/version.rb,
lib/rom/repository/command_proxy.rb,
lib/rom/repository/header_builder.rb,
lib/rom/repository/mapper_builder.rb,
lib/rom/repository/relation_proxy.rb,
lib/rom/repository/struct_builder.rb,
lib/rom/repository/class_interface.rb,
lib/rom/repository/command_compiler.rb,
lib/rom/repository/struct_attributes.rb,
lib/rom/repository/relation_proxy/wrap.rb

Overview

Abstract repository class to inherit from

A repository provides access to composable relations and commands. Its job is to provide application-specific data that is already materialized, so that relations don’t leak into your application layer.

Typically, you’re going to work with Repository::Root that are configured to use a single relation as its root, and compose aggregates and use commands against the root relation.

Examples:

class MyRepo < ROM::Repository[:users]
  relations :users, :tasks

  def users_with_tasks
    users.combine_children(tasks: tasks).to_a
  end
end

rom = ROM.container(:sql, 'sqlite::memory') do |conf|
  conf.default.create_table(:users) do
    primary_key :id
    column :name, String
  end

  conf.default.create_table(:tasks) do
    primary_key :id
    column :user_id, Integer
    column :title, String
  end
end

my_repo = MyRepo.new(rom)
my_repo.users_with_tasks

See Also:

Direct Known Subclasses

Base, Root

Defined Under Namespace

Modules: ClassInterface Classes: Base, CommandCompiler, CommandProxy, HeaderBuilder, MapperBuilder, RelationProxy, Root, StructAttributes, StructBuilder

Constant Summary collapse

VERSION =
'0.3.0'.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ClassInterface

[], inherited

Constructor Details

#initialize(container) ⇒ Repository

Initializes a new repo by establishing configured relation proxies from the passed container

Parameters:

  • container (ROM::Container)

    The rom container with relations and optional commands



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rom/repository.rb', line 80

def initialize(container)
  @container = container
  @mappers = MapperBuilder.new
  @relations = RelationRegistry.new do |registry, relations|
    self.class.relations.each do |name|
      relation = container.relation(name)

      proxy = RelationProxy.new(
        relation, name: name, mappers: mappers, registry: registry
      )

      instance_variable_set("@#{name}", proxy)

      relations[name] = proxy
    end
  end
end

Instance Attribute Details

#containerObject (readonly)



64
65
66
# File 'lib/rom/repository.rb', line 64

def container
  @container
end

#mappersObject (readonly)



72
73
74
# File 'lib/rom/repository.rb', line 72

def mappers
  @mappers
end

#relationsObject (readonly)



68
69
70
# File 'lib/rom/repository.rb', line 68

def relations
  @relations
end

Instance Method Details

#changeset(name, attributes) ⇒ Changeset::Create #changeset(name, restriction_arg, attributes) ⇒ Changeset::Update

Overloads:

  • #changeset(name, attributes) ⇒ Changeset::Create

    Returns a create changeset for a given relation identifier

    Examples:

    repo.changeset(:users, name: "Jane")
    

    Parameters:

    • name (Symbol)

      The relation container identifier

    • attributes (Hash)

    Returns:

  • #changeset(name, restriction_arg, attributes) ⇒ Changeset::Update

    Returns an update changeset for a given relation identifier

    Examples:

    repo.changeset(:users, 1, name: "Jane Doe")
    

    Parameters:

    • name (Symbol)

      The relation container identifier

    • restriction_arg (Object)

      The argument passed to restricted view

    Returns:



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/rom/repository.rb', line 168

def changeset(*args)
  if args.size == 2
    name, data = args
  elsif args.size == 3
    name, pk, data = args
  else
    raise ArgumentError, 'Repository#changeset accepts 2 or 3 arguments'
  end

  relation = relations[name]

  if pk
    Changeset::Update.new(relation, data, primary_key: pk)
  else
    Changeset::Create.new(relation, data)
  end
end

#command(type, relation) ⇒ ROM::Command #command(options) ⇒ ROM::Command #command(rel_name) ⇒ CommandRegistry #command(rel_name, &block) ⇒ ROM::Command

Overloads:

  • #command(type, relation) ⇒ ROM::Command

    Returns a command for a relation

    Examples:

    repo.command(:create, repo.users)
    

    Parameters:

    • type (Symbol)

      The command type (:create, :update or :delete)

    • relation (RelationProxy)

      The relation for which command should be built for

  • #command(options) ⇒ ROM::Command

    Builds a command for a given relation identifier

    Examples:

    repo.command(create: :users)
    

    Parameters:

    • options (Hash<Symbol=>Symbol>)

      A type => rel_name map

  • #command(rel_name) ⇒ CommandRegistry

    Returns command registry for a given relation identifier

    Examples:

    repo.command(:users)[:my_custom_command]
    

    Parameters:

    • rel_name (Symbol)

      The relation identifier from the container

    Returns:

    • (CommandRegistry)
  • #command(rel_name, &block) ⇒ ROM::Command

    Yields a command graph composer for a given relation identifier

    Parameters:

    • rel_name (Symbol)

      The relation identifier from the container

Returns:

  • (ROM::Command)


133
134
135
136
137
138
139
140
141
142
143
# File 'lib/rom/repository.rb', line 133

def command(*args, **opts, &block)
  all_args = args + opts.to_a.flatten

  if all_args.size > 1
    commands.fetch_or_store(all_args.hash) do
      compile_command(*args, **opts)
    end
  else
    container.command(*args, &block)
  end
end