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.



21
22
23
# File 'lib/praxis/links.rb', line 21

def links
  @links
end

Class Method Details

._finalize!Object



49
50
51
52
53
54
55
# File 'lib/praxis/links.rb', line 49

def self._finalize!
  super
  if @attribute
    self.define_default_view
    self.fixup_reference_struct_methods
  end
end

.construct(constructor_block, options) ⇒ Object



37
38
39
40
41
42
43
# File 'lib/praxis/links.rb', line 37

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

  self.attributes(options, &constructor_block)
  self
end

.define_blueprint_reader!(name) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/praxis/links.rb', line 57

def self.define_blueprint_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.type.new(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

    @reference.attribute.type.instance_eval do
      define_method(using) do
        self.send(name)
      end
    end
  end

end

.define_default_viewObject



88
89
90
91
92
93
94
95
# File 'lib/praxis/links.rb', line 88

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

.describe(shallow = false) ⇒ Object



45
46
47
# File 'lib/praxis/links.rb', line 45

def self.describe(shallow=false)
  super(false) # 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.



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

def self.fixup_reference_struct_methods
  self.links.each do |name, using|
    next if @reference.attribute.attributes.has_key?(name)
    @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



24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/praxis/links.rb', line 24

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

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

  reference.const_set :Links, klass
end