Class: ROM::Struct

Inherits:
Dry::Struct
  • Object
show all
Defined in:
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.

There is a caveat you should know about when working with 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.setup(:sql, 'sqlite::memory') do |conf|
  conf.default.create_table(:users) do
    primary_key :id
    column :name, String
  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}>]>

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 = user_repo.users.by_pk(1).one!
user.name # => "Jane"
user.upcased_name # => "JANE"

See Also:

Constant Summary collapse

MissingAttribute =
Class.new(NameError)

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject (private)



93
94
95
96
97
# File 'lib/rom/struct.rb', line 93

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

Instance Method Details

#fetch(name) ⇒ Object

Return attribute value

Parameters:

  • name (Symbol)

    The attribute name



82
83
84
# File 'lib/rom/struct.rb', line 82

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)


87
88
89
# File 'lib/rom/struct.rb', line 87

def respond_to_missing?(*)
  super
end