Class: ROM::Struct

Inherits:
Dry::Struct
  • Object
show all
Defined in:
core/lib/rom/struct.rb

Overview

Simple data-struct class

ROM structs are plain data structures loaded by repositories. They implement Hash protocol which means that they can be used in places where Hash-like objects are supported.

Repositories define subclasses of ROM::Struct automatically, they are defined in the ROM::Struct namespace by default, but you set it up to use your namespace/module as well.

Structs are based on dry-struct gem, they include schema with detailed information about attribute types returned from relations, thus can be introspected to build additional functionality when desired.

NOTE: There is a caveat you should know about when working with ROM structs. Struct classes have names but at the same time they're anonymous, i.e. you can't get the User struct class with ROM::Struct::User. ROM will create as many struct classes for User as needed, they all will have the same name and ROM::Struct::User will be the common parent class for them. Combined with the ability to provide your own namespace for structs this enables to pre-define the parent class.

Examples:

accessing relation struct model

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

  conf.relation(:users) do
    schema(infer: true)
    auto_struct true
  end
end

class UserRepo < ROM::Repository[:users]
end

user_repo = UserRepo.new(rom)

# get auto-generated User struct
model = user_repo.users.mapper.model
# => ROM::Struct::User

# see struct's schema attributes

model.schema.key(:id)
# => #<Dry::Types[id: Nominal<Integer meta={primary_key: true, source: :users}>]>

model.schema[:name]
# => #<Dry::Types[name: Sum<Nominal<NilClass> | Nominal<String meta={source: :users}> meta={source: :users}>]>

passing a namespace with an existing parent class

module Entities
  class User < ROM::Struct
    def upcased_name
      name.upcase
    end
  end
end

class UserRepo < ROM::Repository[:users]
  struct_namespace Entities
end

user_repo = UserRepo.new(rom)
user_repo.users.insert(name: "Jane")
user = user_repo.users.by_pk(1).one!
user.name # => "Jane"
user.upcased_name # => "JANE"

See Also:

Constant Summary collapse

MissingAttribute =
Class.new(NameError) do
  def initialize(&block)
    super
    @message_proc = block
  end

  def message
    @message_proc.call
  end
end

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject (private)



107
108
109
110
111
# File 'core/lib/rom/struct.rb', line 107

def method_missing(*)
  super
rescue NameError => error
  raise MissingAttribute.new { "#{error.message} (attribute not loaded?)" }
end

Instance Method Details

#fetch(name) ⇒ Object

Return attribute value

Parameters:

  • name (Symbol)

    The attribute name



96
97
98
# File 'core/lib/rom/struct.rb', line 96

def fetch(name)
  __send__(name)
end

#respond_to_missing?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns:

  • (Boolean)


101
102
103
# File 'core/lib/rom/struct.rb', line 101

def respond_to_missing?(*)
  super
end