Class: Wallaby::ResourceDecorator

Inherits:
Object
  • Object
show all
Extended by:
Baseable::ClassMethods
Defined in:
lib/decorators/wallaby/resource_decorator.rb

Overview

Decorator base class. It’s designed to be used as the decorator (AKA presenter/view object) for the associated model instance (which means it should be used in the views only).

And it holds the following field metadata information for associated model class:

For better practice, please create an application decorator class (see example) to better control the functions shared between different decorators.

Examples:

Create an application class for Admin Interface usage

class Admin::ApplicationDecorator < Wallaby::ResourceDecorator
  base_class!
end

Constant Summary collapse

DELEGATE_METHODS =
ModelDecorator.public_instance_methods(false) + Fieldable.public_instance_methods(false) - %i[model_class]

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes included from Baseable::ClassMethods

#base_class

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Baseable::ClassMethods

base_class!, base_class?, namespace, namespace=

Constructor Details

#initialize(resource) ⇒ ResourceDecorator

Returns a new instance of ResourceDecorator.

Parameters:

  • resource (Object)


142
143
144
145
# File 'lib/decorators/wallaby/resource_decorator.rb', line 142

def initialize(resource)
  @resource = resource
  @model_decorator = self.class.model_decorator(model_class)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_id, *args, &block) ⇒ Object

Delegate missing method to #resource



210
211
212
213
214
215
216
217
218
# File 'lib/decorators/wallaby/resource_decorator.rb', line 210

def method_missing(method_id, *args, &block)
  if resource.respond_to?(method_id)
    resource.try(method_id, *args, &block)
  elsif model_decorator.respond_to?(method_id)
    model_decorator.try(method_id, *args, &block)
  else
    super
  end
end

Class Attribute Details

.field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 59

.fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Origin fields metadata.

Initially, #index_fields, #show_fields and #form_fields are copies of it.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 56

.form_field_namesArray<String, Symbol>

A list of field names for form (‘new`/`edit`) page

Returns:

  • (Array<String, Symbol>)


80
# File 'lib/decorators/wallaby/resource_decorator.rb', line 80

delegate(*DELEGATE_METHODS, to: :model_decorator, allow_nil: true)

.form_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for form (‘new`/`edit`) page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 74

.hActionView::Base

Returns Wallaby::ResourcesController‘s helpers.

Returns:



98
99
100
# File 'lib/decorators/wallaby/resource_decorator.rb', line 98

def h
  @h ||= superclass.try(:h) || ResourcesController.helpers
end

.index_field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 65

.index_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for ‘index` page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 62

.readonly=(value) ⇒ Object (writeonly)

Sets the attribute readonly

Parameters:

  • value

    the value to set the attribute readonly to.



103
104
105
# File 'lib/decorators/wallaby/resource_decorator.rb', line 103

def readonly=(value)
  @readonly = value
end

.show_field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 71

.show_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for ‘show` page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 68

Instance Attribute Details

#field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 31

#fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Origin fields metadata.

Initially, #index_fields, #show_fields and #form_fields are copies of it.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 28

#form_field_namesArray<String, Symbol>

A list of field names for form (‘new`/`edit`) page

Returns:

  • (Array<String, Symbol>)


52
53
# File 'lib/decorators/wallaby/resource_decorator.rb', line 52

DELEGATE_METHODS =
ModelDecorator.public_instance_methods(false) + Fieldable.public_instance_methods(false) - %i[model_class]

#form_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for form (‘new`/`edit`) page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 46

#index_field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 37

#index_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for ‘index` page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 34

#model_decoratorModelDecorator (readonly)

Returns:



129
130
131
# File 'lib/decorators/wallaby/resource_decorator.rb', line 129

def model_decorator
  @model_decorator
end

#resourceObject (readonly)

Returns:

  • (Object)


125
126
127
# File 'lib/decorators/wallaby/resource_decorator.rb', line 125

def resource
  @resource
end

#show_field_namesObject



# File 'lib/decorators/wallaby/resource_decorator.rb', line 43

#show_fieldsActiveSupport::HashWithIndifferentAccess

Note:

to be implemented in subclasses.

Fields metadata for ‘show` page.

Returns:

  • (ActiveSupport::HashWithIndifferentAccess)


# File 'lib/decorators/wallaby/resource_decorator.rb', line 40

Class Method Details

.method_missing(method_id, *args, &block) ⇒ Object

Delegate missing method to model_decorator



110
111
112
113
114
115
# File 'lib/decorators/wallaby/resource_decorator.rb', line 110

def method_missing(method_id, *args, &block)
  return if ModelDecorator::MISSING_METHODS_RELATED_TO_FIELDS.match?(method_id.to_s) && model_decorator.blank?
  return super unless model_decorator.try(:respond_to?, method_id)

  model_decorator.try(method_id, *args, &block)
end

.model_decorator(model_class = self.model_class) ⇒ ModelDecorator?

Return associated model decorator. It is the instance that pull out all the metadata information from the associated model.

Parameters:

  • model_class (Class) (defaults to: self.model_class)

Returns:

  • (ModelDecorator)
  • (nil)

    if itself is a base class or the given model_class is blank



87
88
89
90
91
# File 'lib/decorators/wallaby/resource_decorator.rb', line 87

def model_decorator(model_class = self.model_class)
  return if model_class.blank?

  Map.model_decorator_map(model_class, base_class)
end

.readonly?Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/decorators/wallaby/resource_decorator.rb', line 105

def readonly?
  @readonly
end

.respond_to_missing?(method_id, _include_private) ⇒ Boolean

Delegate missing method check to model_decorator

Returns:

  • (Boolean)


118
119
120
# File 'lib/decorators/wallaby/resource_decorator.rb', line 118

def respond_to_missing?(method_id, _include_private)
  model_decorator.try(:respond_to?, method_id) || super
end

Instance Method Details

#errorsHash, Array

Returns validation/result errors.

Returns:

  • (Hash, Array)

    validation/result errors



172
173
174
# File 'lib/decorators/wallaby/resource_decorator.rb', line 172

def errors
  model_decorator.form_active_errors(resource)
end

#hActionView::Base

Returns Wallaby::ResourcesController‘s helpers.

Returns:

See Also:



133
134
135
# File 'lib/decorators/wallaby/resource_decorator.rb', line 133

def h
  self.class.h
end

#model_classClass

Returns resource’s class.

Returns:

  • (Class)

    resource’s class



148
149
150
# File 'lib/decorators/wallaby/resource_decorator.rb', line 148

def model_class
  resource.class
end

#model_nameActiveModel::Name

Note:

this method is for the Rails URL helper methods to recognize non-ActiveModel models

Returns:

  • (ActiveModel::Name)


185
186
187
# File 'lib/decorators/wallaby/resource_decorator.rb', line 185

def model_name
  resource.try(:model_name) || ActiveModel::Name.new(model_class)
end

#primary_key_valueObject

Returns primary key value.

Returns:

  • (Object)

    primary key value



177
178
179
180
181
# File 'lib/decorators/wallaby/resource_decorator.rb', line 177

def primary_key_value
  return if primary_key.blank?

  resource.try primary_key
end

#readonly?true, false

Returns:

  • (true, false)

    if resource responds to method ‘.readonly?`

  • (false)

    otherwise



205
206
207
# File 'lib/decorators/wallaby/resource_decorator.rb', line 205

def readonly?
  resource.try(:readonly?) || self.class.try(:readonly?)
end

#respond_to_missing?(method_id, _include_private) ⇒ Boolean

Delegate missing method check to #resource

Returns:

  • (Boolean)


221
222
223
# File 'lib/decorators/wallaby/resource_decorator.rb', line 221

def respond_to_missing?(method_id, _include_private)
  [resource, model_decorator].any? { |v| v.respond_to?(method_id) } || super
end

#to_keynil, Array<String>

Note:

this method is for the Rails form helper methods to recognize non-ActiveModel models

Returns:

  • (nil)

    if no primary key

  • (Array<String>)

    primary key



198
199
200
201
# File 'lib/decorators/wallaby/resource_decorator.rb', line 198

def to_key
  key = resource.try primary_key
  key ? [key] : nil
end

#to_labelString

Guess the title for given resource.

It falls back to primary key value when no text field is found.

Returns:

  • (String)

    a label



164
165
166
167
168
169
# File 'lib/decorators/wallaby/resource_decorator.rb', line 164

def to_label
  # NOTE: `.to_s` at the end is to ensure String is returned.
  # There is an issue when {#to_label} returns an integer value, and it is used in a #link_to block,
  # the #link_to will generate empty link text when integer value is given in the block.
  (model_decorator.guess_title(resource) || primary_key_value).to_s
end

#to_modelObject

Note:

This overwritten method is a response to the above change



191
192
193
# File 'lib/decorators/wallaby/resource_decorator.rb', line 191

def to_model
  self
end

#value_of(field_name) ⇒ Object

Returns value of given field name.

Parameters:

  • field_name (String, Symbol)

Returns:

  • (Object)

    value of given field name



154
155
156
157
158
# File 'lib/decorators/wallaby/resource_decorator.rb', line 154

def value_of(field_name)
  return unless field_name

  resource.try field_name
end