Class: Praxis::Links

Inherits:
Blueprint
  • Object
show all
Defined in:
lib/praxis/links.rb

Overview

Container for links for a given type

Defined Under Namespace

Classes: DSLCompiler

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

Returns the value of attribute links.



24
25
26
# File 'lib/praxis/links.rb', line 24

def links
  @links
end

Class Method Details

._finalize!Object



57
58
59
60
61
62
63
64
65
# File 'lib/praxis/links.rb', line 57

def self._finalize!
  super
  if @attribute
    # Master and default views must be set for all attributes, always using their :link view
    self.define_default_view
    self.define_master_view
    self.fixup_reference_struct_methods
  end
end

.construct(constructor_block, options) ⇒ Object



45
46
47
48
49
50
51
# File 'lib/praxis/links.rb', line 45

def self.construct(constructor_block, options)
  options[:reference] = @reference
  options[:dsl_compiler_options] = {links: self.links}

  self.attributes(options, &constructor_block)
  self
end

.constructable?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/praxis/links.rb', line 41

def self.constructable?
  true
end

.define_default_viewObject



92
93
94
95
96
97
98
99
# File 'lib/praxis/links.rb', line 92

def self.define_default_view
  return unless view(:default).nil?

  view(:default) {}
  self.attributes.each do |name, attribute|
    view(:default).attribute(name, view: :link)
  end
end

.define_master_viewObject



101
102
103
104
105
106
107
# File 'lib/praxis/links.rb', line 101

def self.define_master_view

  view(:master) {}
  self.attributes.each do |name, attribute|
    view(:master).attribute(name, view: :link)
  end
end

.define_reader!(name) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/praxis/links.rb', line 67

def self.define_reader!(name)
  # it's faster to use define_method in this case than module_eval
  # because we save the attribute lookup on every access.
  attribute = self.attributes[name]
  using = self.links.fetch(name) do
    raise Exceptions::InvalidConfiguration.new("Cannot define attribute for #{name.inspect}")
  end

  define_method(name) do
    value = @object.__send__(using)
    return value if value.nil? || value.kind_of?(attribute.type)
    attribute.load(value)
  end

  # do whatever crazy aliasing we need to here....
  unless name == using
    @attribute.type.instance_eval do
      define_method(using) do
        self.__send__(name)
      end
    end
  end

end

.describe(shallow = false, **opts) ⇒ Object



53
54
55
# File 'lib/praxis/links.rb', line 53

def self.describe(shallow=false,**opts)
  super(false,**opts) # Links must always describe attributes
end

.fixup_reference_struct_methodsObject

Define methods on the inner Struct class for links that do not have corresponding top-level attributes. This is primarily necessary only for example generation.



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/praxis/links.rb', line 112

def self.fixup_reference_struct_methods
  self.links.each do |name, using|
    next if @reference.attribute.attributes.has_key?(using)
    @reference.attribute.type.instance_eval do
      define_method(using) do
        return nil unless attributes[:links]
        attributes[:links].__send__(name)
      end
    end
  end
end

.for(reference) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/praxis/links.rb', line 27

def self.for(reference)
  if defined?(reference::Links)
    return reference::Links
  end

  klass = Class.new(self) do
    @reference = reference
    @links = Hash.new
    anonymous_type
  end

  reference.const_set :Links, klass
end

.validate(*args) ⇒ Object



124
125
126
127
# File 'lib/praxis/links.rb', line 124

def self.validate(*args)
  # FIXME: what to validate for links?
  []
end