Module: WCC::Contentful::ModelMethods
- Defined in:
- lib/wcc/contentful/model_methods.rb
Overview
This module is included by all models and defines instance methods that are not dynamically generated.
Instance Method Summary collapse
-
#resolve(depth: 1, fields: nil, context: {}, **options) ⇒ Object
Resolves all links in an entry to the specified depth.
-
#resolved?(depth: 1, fields: nil) ⇒ Boolean
Determines whether the object has been resolved up to the prescribed depth.
-
#to_h(stack = nil) ⇒ Object
Turns the current model into a hash representation as though it had been retrieved from the Contentful API.
Instance Method Details
#resolve(depth: 1, fields: nil, context: {}, **options) ⇒ Object
Resolves all links in an entry to the specified depth.
Each link in the entry is recursively retrieved from the store until the given depth is satisfied. Depth resolution is unlimited, circular references will be resolved to the same object.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/wcc/contentful/model_methods.rb', line 25 def resolve(depth: 1, fields: nil, context: {}, **) raise ArgumentError, "Depth must be > 0 (was #{depth})" unless depth && depth > 0 return self if resolved?(depth: depth, fields: fields) fields = fields.map { |f| f.to_s.camelize(:lower) } if fields.present? fields ||= self.class::FIELDS typedef = self.class.content_type_definition links = fields.select { |f| i[Asset Link].include?(typedef.fields[f].type) } raw_links = links.any? do |field_name| raw_value = raw.dig('fields', field_name, sys.locale) if raw_value&.is_a? Array raw_value.any? { |v| v&.dig('sys', 'type') == 'Link' } elsif raw_value raw_value.dig('sys', 'type') == 'Link' end end if raw_links # use include param to do resolution raw = self.class.store.find_by(content_type: self.class.content_type, filter: { 'sys.id' => id }, options: { include: [depth, 10].min }) unless raw raise WCC::Contentful::ResolveError, "Cannot find #{self.class.content_type} with ID #{id}" end @raw = raw.freeze links.each { |f| instance_variable_set('@' + f, raw.dig('fields', f, sys.locale)) } end links.each { |f| _resolve_field(f, depth, context, ) } self end |
#resolved?(depth: 1, fields: nil) ⇒ Boolean
Determines whether the object has been resolved up to the prescribed depth.
62 63 64 65 66 67 68 69 70 71 |
# File 'lib/wcc/contentful/model_methods.rb', line 62 def resolved?(depth: 1, fields: nil) raise ArgumentError, "Depth must be > 0 (was #{depth})" unless depth && depth > 0 fields = fields.map { |f| f.to_s.camelize(:lower) } if fields.present? fields ||= self.class::FIELDS typedef = self.class.content_type_definition links = fields.select { |f| i[Asset Link].include?(typedef.fields[f].type) } links.all? { |f| _resolved_field?(f, depth) } end |
#to_h(stack = nil) ⇒ Object
Turns the current model into a hash representation as though it had been retrieved from the Contentful API.
This differs from ‘#raw` in that it recursively includes the `#to_h` of resolved links. It also sets the fields to the value for the entry’s ‘#sys.locale`, as though the entry had been retrieved from the API with `locale=WCC::Contentful::ModelMethods#sys#sys.locale` rather than `locale=*`.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/wcc/contentful/model_methods.rb', line 80 def to_h(stack = nil) raise WCC::Contentful::CircularReferenceError.new(stack, id) if stack&.include?(id) stack = [*stack, id] typedef = self.class.content_type_definition fields = typedef.fields.each_with_object({}) do |(name, field_def), h| if field_def.type == :Link || field_def.type == :Asset if _resolved_field?(name, 0) val = public_send(name) val = _try_map(val) { |v| v.to_h(stack) } else ids = field_def.array ? public_send("#{name}_ids") : public_send("#{name}_id") val = _try_map(ids) do |id| { 'sys' => { 'type' => 'Link', 'linkType' => field_def.type == :Asset ? 'Asset' : 'Entry', 'id' => id } } end end else val = public_send(name) val = _try_map(val) { |v| v.respond_to?(:to_h) ? v.to_h.stringify_keys! : v } end h[name] = val end { 'sys' => { 'locale' => @sys.locale }.merge!(@raw['sys']), 'fields' => fields } end |