Module: Gourami::Extensions::Resources

Defined in:
lib/gourami/extensions/resources.rb

Instance Method Summary collapse

Instance Method Details

#any_errors?Boolean

Determine if current form instance is valid by running the validations

specified on #validate.

Returns:

  • (Boolean)


194
195
196
# File 'lib/gourami/extensions/resources.rb', line 194

def any_errors?
  super || any_resource_errors?
end

#any_resource_errors?Boolean

Return true if any resources by any uids have any errors.

Returns:

  • (Boolean)


201
202
203
# File 'lib/gourami/extensions/resources.rb', line 201

def any_resource_errors?
  resource_errors.values.flat_map(&:values).map(&:values).flatten.any?
end

#append_error(attribute_name, message) ⇒ Object

If a resource namespace is active (within with_resource block), append the error to the resource. Otherwise, append the error to the form object.



100
101
102
103
104
105
106
# File 'lib/gourami/extensions/resources.rb', line 100

def append_error(attribute_name, message)
  if @resource_namespace
    append_resource_error(@resource_namespace, @offset ? @resource_uid + @offset : @resource_uid, attribute_name, message)
  else
    super
  end
end

#append_resource_error(resource_namespace, resource_uid, attribute_name, error) ⇒ Object

Append an error to the given attribute for a resource. TODO: consider coercing attribute_name ‘.to_s` too.

Parameters:

  • resource_namespace (Symbol)
  • resource_uid (String)
  • attribute_name (Symbol)
  • error (Symbol, String)

    The error identifier.



186
187
188
# File 'lib/gourami/extensions/resources.rb', line 186

def append_resource_error(resource_namespace, resource_uid, attribute_name, error)
  resource_errors[resource_namespace][resource_uid&.to_s][attribute_name] << error
end

#clear_and_set_resource_errors(new_resource_errors) ⇒ Hash<Symbol, Hash<Symbol, Hash<Symbol, Array>>>

Replace the existing resource errors with the provided errors Hash.

Parameters:

  • new_resource_errors (Hash<Symbol, Hash<Symbol, Hash<Symbol, Array>>>)

Returns:

  • (Hash<Symbol, Hash<Symbol, Hash<Symbol, Array>>>)


210
211
212
213
214
215
216
# File 'lib/gourami/extensions/resources.rb', line 210

def clear_and_set_resource_errors(new_resource_errors)
  new_resource_errors = new_resource_errors.dup
  resource_errors.clear
  resource_errors.merge!(new_resource_errors)

  resource_errors
end

#current_resourceObject

If a resource namespace is active (within with_resource block), find the resource using the namespace and uid. Otherwise, return the form object.



88
89
90
91
92
93
94
95
96
# File 'lib/gourami/extensions/resources.rb', line 88

def current_resource
  if @resource_namespace && @resource_uid
    send(@resource_namespace)[@resource_uid]
  elsif @resource_namespace
    send(@resource_namespace)
  else
    super
  end
end

#handle_validation_error(error) ⇒ Object



218
219
220
221
# File 'lib/gourami/extensions/resources.rb', line 218

def handle_validation_error(error)
  super(error)
  clear_and_set_resource_errors(error.resource_errors) unless error.resource_errors.nil?
end

#raise_validate_errorsObject

Raises:



223
224
225
# File 'lib/gourami/extensions/resources.rb', line 223

def raise_validate_errors
  raise ValidationError.new(errors, resource_errors)
end

#resource_attribute_has_errors?(resource_namespace, resource_uid_or_attribute_name, attribute_name = nil) ⇒ Boolean

TODO: YARD

Returns:

  • (Boolean)


166
167
168
169
170
171
172
173
174
175
176
# File 'lib/gourami/extensions/resources.rb', line 166

def resource_attribute_has_errors?(resource_namespace, resource_uid_or_attribute_name, attribute_name = nil)
  if attribute_name.nil?
    # 2 arguments: resource_namespace, attribute_name
    attribute_name = resource_uid_or_attribute_name
    resource_uid = nil
  else
    # 3 arguments: resource_namespace, resource_uid, attribute_name
    resource_uid = resource_uid_or_attribute_name
  end
  resource_errors[resource_namespace][resource_uid&.to_s][attribute_name].any?
end

#resource_errorsHash<Symbol>

Return a deeply nested Hash which allows you to identify errors by resource.

Examples:

resource_errors
# => {
#   :social_broadcasts => {
#     :"facebook_page-41" => {
#       :trim_start_time => [:is_invalid, :is_too_short],
#       :trim_end_time => [:is_invalid]
#     },
#     :"youtube_account-42" => {
#       :title => [:is_too_short]
#     }
#   },
#   :another_resource => {
#     :"other_resource_id-12" => {
#       :something => [:is_too_long]
#     }
#   }
# }

resource_errors[:social_broadcasts]
# => {
#   :"facebook_page-41" => {
#     :trim_start_time => [:is_invalid, :is_too_short],
#     :trim_end_time => [:is_invalid]
#   },
#   :"youtube_account-42" => {
#     :title => [:is_too_short]
#   }
# }

resource_errors[:social_broadcasts][:"facebook_page-41"]
# => {
#   :trim_start_time => [:is_invalid, :is_too_short],
#   :trim_end_time => [:is_invalid]
# }

resource_errors[:social_broadcasts][:"facebook_page-41"][:trim_start_time]
# => [:is_invalid, :is_too_short]

Returns:

  • (Hash<Symbol>)


150
151
152
153
154
155
156
157
158
# File 'lib/gourami/extensions/resources.rb', line 150

def resource_errors
  @resource_errors ||= Hash.new do |resource_errors, resource_name|
    resource_errors[resource_name] = Hash.new do |resource_uids, resource_uid|
      resource_uids[resource_uid] = Hash.new do |attributes, attribute_name|
        attributes[attribute_name] = []
      end
    end
  end
end

#resource_has_errors?(resource_namespace, resource_uid = nil) ⇒ Boolean

TODO: YARD

Returns:

  • (Boolean)


161
162
163
# File 'lib/gourami/extensions/resources.rb', line 161

def resource_has_errors?(resource_namespace, resource_uid = nil)
  resource_errors[resource_namespace][resource_uid&.to_s].values.map(&:flatten).any?
end

#with_each_resource(resource_namespace, offset: nil) { ... } ⇒ Object

yield to the given block for each resource in the given namespace.

Examples:

def validate
  with_each_resource(:social_broadcasts) do
    validate_presence(:title) # validates `attributes[:social_broadcasts][<EACH>][:title]`
  end
end
def validate
  with_each_resource(:items, offset: existing_items.count) do |item, key, index|
    # Standard validation methods are available, and will validate the attributes on the resource:
    validate_decimal_places(:price, max: 2)

    # You may reference the resource object directly to perform custom validation logic inline:
    append_error(:password_confirmation, :doesnt_match) if item["password"] != item["password_confirmation"]

    # If `items` is a Hash, `key` is the hash key of the resource.
    # If `items` is an Array, `key` is the index of the resource (`+ offset`, if an offset is given).
    validate_length(:name, max: 255) if key % 2 == 0

    # If `items` is a Hash, `index` is the hash key of the resource.
    # If `items` is an Array, `index` is the index of the resource (offset is NOT applied to index).
    append_error(:id, :is_invalid) if index > 500
  end
end

Parameters:

  • resource_namespace (Symbol)

    The namespace of the resource (e.g. :users, :payments)

  • offset (Hash) (defaults to: nil)

    a customizable set of options

Options Hash (offset:):

  • The (Integer)

    offset of the resource (e.g. 0, 1, 2) for example in an update form, there may be existing items that already exist, however only the new items are sent to the form.

Yields:

  • The block to execute, each time with a resource active.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/gourami/extensions/resources.rb', line 38

def with_each_resource(resource_namespace, offset: nil, &_block)
  resources = send(resource_namespace)
  if resources.is_a?(Hash)
    return resources.each_with_index do |(key, resource), index|
      with_resource(resource_namespace, key, offset: offset) do
        yield(resource, key, index)
      end
    end
  end

  send(resource_namespace).each_with_index do |resource, index|
    with_resource(resource_namespace, index, offset: offset) do
      yield(resource, offset ? index + offset : index, index)
    end
  end
end

#with_resource(resource_namespace, resource_uid = nil, offset: nil) { ... } ⇒ Object

For the duration of the given block, all validations will be done on the given resource.

Examples:

def validate
  validate_presence(:title) # validates `attributes[:title]` of the form

  with_resource(:social_broadcasts, "facebook_page-41") do
    # Within this block all validations will be done on the resource.
    validate_presence(:title)           # validates `attributes[:social_broadcasts]["facebook_page-41"][:title]`
    validate_presence(:trim_start_time) # validates `attributes[:social_broadcasts]["facebook_page-41"][:trim_start_time]`
    validate_presence(:trim_end_time)   # validates `attributes[:social_broadcasts]["facebook_page-41"][:trim_end_time]`
  end
end

Parameters:

  • resource_namespace (Symbol)

    The namespace of the resource (e.g. :users, :payments)

  • resource_uid (String|Number) (defaults to: nil)

    The uid of the resource (e.g. 0, 1, “123”)

  • offset (Hash) (defaults to: nil)

    a customizable set of options

Options Hash (offset:):

  • The (Integer)

    offset of the resource (e.g. 0, 1, 2) for example in an update form, there may be existing items that already exist, however only the new items are sent to the form.

Yields:

  • The block to execute with the resource active.



75
76
77
78
79
80
81
82
83
84
# File 'lib/gourami/extensions/resources.rb', line 75

def with_resource(resource_namespace, resource_uid = nil, offset: nil, &_block)
  @resource_namespace = resource_namespace
  @resource_uid = resource_uid
  @offset = offset
  yield
ensure
  @resource_namespace = nil
  @resource_uid = nil
  @offset = nil
end