Class: Phlexi::Field::Structure::Namespace

Inherits:
Node
  • Object
show all
Includes:
Enumerable
Defined in:
lib/phlexi/field/structure/namespace.rb

Overview

A Namespace maps an object to values, but doesn’t actually have a value itself. For example, a ‘User` object or ActiveRecord model could be passed into the `:user` namespace.

To access single values on a Namespace, #field can be used.

To access nested objects within a namespace, two methods are available:

  1. #nest_one: Used for single nested objects, such as if a ‘User belongs_to :profile` in ActiveRecord. This method returns another Namespace object.

  2. #nest_many: Used for collections of nested objects, such as if a ‘User has_many :addresses` in ActiveRecord. This method returns a NamespaceCollection object.

Defined Under Namespace

Classes: NamespaceCollection

Instance Attribute Summary collapse

Attributes inherited from Node

#key, #parent

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Node

#inspect

Constructor Details

#initialize(key, parent:, builder_klass:, object: nil, dom_id: nil) {|_self| ... } ⇒ Namespace

Returns a new instance of Namespace.

Yields:

  • (_self)

Yield Parameters:



25
26
27
28
29
30
31
32
# File 'lib/phlexi/field/structure/namespace.rb', line 25

def initialize(key, parent:, builder_klass:, object: nil, dom_id: nil)
  super(key, parent: parent)
  @builder_klass = builder_klass
  @object = object
  @dom_id = dom_id
  @children = {}
  yield self if block_given?
end

Instance Attribute Details

#builder_klassObject (readonly)

Returns the value of attribute builder_klass.



23
24
25
# File 'lib/phlexi/field/structure/namespace.rb', line 23

def builder_klass
  @builder_klass
end

#objectObject (readonly)

Returns the value of attribute object.



23
24
25
# File 'lib/phlexi/field/structure/namespace.rb', line 23

def object
  @object
end

Class Method Details

.root(builder_klass:) ⇒ Object

Creates a root Namespace.



100
101
102
# File 'lib/phlexi/field/structure/namespace.rb', line 100

def self.root(*, builder_klass:, **, &)
  new(*, parent: nil, builder_klass:, **, &)
end

Instance Method Details

#dom_idObject



88
89
90
91
92
93
94
95
96
97
# File 'lib/phlexi/field/structure/namespace.rb', line 88

def dom_id
  @dom_id ||= begin
    object_id = if object.nil?
      nil
    elsif (primary_key = Phlexi::Field.object_primary_key(object))
      primary_key&.to_s || :new
    end
    [key, object_id].compact.join("_").underscore
  end
end

#eachObject

Iterates through the children of the current namespace, which could be ‘Namespace` or `Field` objects.



84
85
86
# File 'lib/phlexi/field/structure/namespace.rb', line 84

def each(&)
  @children.values.each(&)
end

#field(key, template: false, **attributes) ⇒ Object



34
35
36
37
38
# File 'lib/phlexi/field/structure/namespace.rb', line 34

def field(key, template: false, **attributes)
  create_child(key, attributes.delete(:builder_klass) || builder_klass, object: object, template:, **attributes).tap do |field|
    yield field if block_given?
  end
end

#nest_many(key, as: nil, collection: nil, default: nil, template: false) ⇒ Object

Wraps an array of objects in Namespace classes. For example, if ‘User#addresses` returns an enumerable or array of `Address` classes:

“‘ruby Phlexi::Form(User.new) do

render field(:email).input_tag
render field(:name).input_tag
nest_many :addresses do |address|
  render address.field(:street).input_tag
  render address.field(:state).input_tag
  render address.field(:zip).input_tag
end

end “‘ The object within the block is a `Namespace` object that maps each object within the enumerable to another `Namespace` or `Field`.



76
77
78
79
80
# File 'lib/phlexi/field/structure/namespace.rb', line 76

def nest_many(key, as: nil, collection: nil, default: nil, template: false, &)
  collection ||= Array(object_value_for(key: key)).presence || default
  key = as || key
  create_child(key, self.class::NamespaceCollection, collection:, template:, &)
end

#nest_one(key, as: nil, object: nil, default: nil, template: false) ⇒ Object

Creates a ‘Namespace` child instance with the parent set to the current instance, adds to the `@children` Hash to ensure duplicate child namespaces aren’t created, then calls the method on the ‘@object` to get the child object to pass into that namespace.

For example, if a ‘User#permission` returns a `Permission` object, we could map that to a form like this:

“‘ruby Phlexi::Form(User.new, as: :user) do

nest_one :profile do |profile|
  render profile.field(:gender).input_tag
end

end “‘



54
55
56
57
58
# File 'lib/phlexi/field/structure/namespace.rb', line 54

def nest_one(key, as: nil, object: nil, default: nil, template: false, &)
  object ||= object_value_for(key: key) || default
  key = as || key
  create_child(key, self.class, object:, template:, builder_klass:, &)
end