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



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

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

.construct(constructor_block, options) ⇒ Object



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

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)


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

def self.constructable?
  true
end

.define_default_viewObject



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

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_reader!(name) ⇒ Object



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

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) ⇒ Object



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

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.



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

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
# 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
  end

  reference.const_set :Links, klass
end

.validate(*args) ⇒ Object



113
114
115
116
# File 'lib/praxis/links.rb', line 113

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