Class: Rod::Property::SingularAssociation

Inherits:
Base
  • Object
show all
Defined in:
lib/rod/property/singular_association.rb

Overview

This class defines the has_one (singular association) property. A has_one property has to define its name.

Instance Attribute Summary

Attributes inherited from Base

#name, #options

Instance Method Summary collapse

Methods inherited from Base

#copy, #define_finders, #difference, #has_index?, #index, #reset_index

Constructor Details

#initialize(klass, name, options = {}) ⇒ SingularAssociation

Creates new singular association associated with klass, with given name and options. Valid options are:

  • :class_name - the name of the class (as String) associated with this class

  • :polymorphic - if set to true the association is polymorphic (allows to access objects of different classes via this association).



15
16
17
# File 'lib/rod/property/singular_association.rb', line 15

def initialize(klass,name,options={})
  super(klass,name,options)
end

Instance Method Details

#association?Boolean

Predicate indicating that this property is an association.

Returns:

  • (Boolean)


25
26
27
# File 'lib/rod/property/singular_association.rb', line 25

def association?
  true
end

#define_c_accessors(builder) ⇒ Object

Defines the accessor of the association’s constituents (C struct field/fields that hold the association data).



60
61
62
63
64
65
66
67
# File 'lib/rod/property/singular_association.rb', line 60

def define_c_accessors(builder)
  field_reader(@name,@klass.struct_name,c_type(:ulong),builder)
  field_writer(@name,@klass.struct_name,c_type(:ulong),builder)
  if polymorphic?
    field_reader("#{@name}__class",@klass.struct_name,c_type(:ulong),builder)
    field_writer("#{@name}__class",@klass.struct_name,c_type(:ulong),builder)
  end
end

#define_getterObject

Defines the getter of the Ruby class which corresponds to this association.



76
77
78
79
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
# File 'lib/rod/property/singular_association.rb', line 76

def define_getter
  # optimization
  name = @name.to_s
  property = self
  class_name =
    if @options[:class_name]
      @options[:class_name]
    else
      "#{@klass.scope_name}::#{name.camelcase}"
    end
  klass = options[:polymorphic] ? nil : class_name.constantize
  @klass.send(:define_method,name) do
    value = instance_variable_get("@#{name}")
    if value.nil?
      return nil if self.new?
      rod_id = send("_#{name}",@rod_id)
      # the indices are shifted by 1, to leave 0 for nil
      if rod_id == 0
        value = nil
      else
        if property.polymorphic?
          klass = Model.get_class(send("_#{name}__class",@rod_id))
        end
        value = klass.find_by_rod_id(rod_id)
      end
      # avoid change tracking
      instance_variable_set("@#{name}",value)
    end
    value
  end
end

#define_setterObject

Defines the settor of the Ruby class which corresponds to this association.



109
110
111
112
113
114
115
116
117
118
# File 'lib/rod/property/singular_association.rb', line 109

def define_setter
  # optimization
  name = @name.to_s
  @klass.send(:define_method,"#{name}=") do |value|
    old_value = send(name)
    send("#{name}_will_change!") unless old_value == value
    instance_variable_set("@#{name}", value)
    value
  end
end

#field?Boolean

Predicate indicating that this property is a field.

Returns:

  • (Boolean)


20
21
22
# File 'lib/rod/property/singular_association.rb', line 20

def field?
  false
end

#layoutObject

Returns the memory layout of the C struct fields that correspond to this association.



122
123
124
125
126
127
128
129
# File 'lib/rod/property/singular_association.rb', line 122

def layout
  unless polymorphic?
    "#{@name}[value:#{sizeof(:ulong)}]"
  else
    "#{@name}[value:#{sizeof(:ulong)}+" +
      "class:#{sizeof(:ulong)}]"
  end
end

#metadataObject

Returns the metadata of the association in form of a hash.



45
46
47
# File 'lib/rod/property/singular_association.rb', line 45

def 
  @options.dup
end

#plural?Boolean

Predicate indicating that this property is not a plural association.

Returns:

  • (Boolean)


35
36
37
# File 'lib/rod/property/singular_association.rb', line 35

def plural?
  false
end

#polymorphic?Boolean

Predicate indicating that this property is polymorphic.

Returns:

  • (Boolean)


40
41
42
# File 'lib/rod/property/singular_association.rb', line 40

def polymorphic?
  @options[:polymorphic]
end

#seal_c_accessorsObject

Make the C accessors private.



70
71
72
73
# File 'lib/rod/property/singular_association.rb', line 70

def seal_c_accessors
  @klass.send(:private,"_#{@name}")
  @klass.send(:private,"_#{@name}=")
end

#singular?Boolean

Predicate indicating that this property is a singular association.

Returns:

  • (Boolean)


30
31
32
# File 'lib/rod/property/singular_association.rb', line 30

def singular?
  true
end

#to_c_structObject

Converts the association to fields in a C struct.



50
51
52
53
54
55
56
# File 'lib/rod/property/singular_association.rb', line 50

def to_c_struct
  result = "  #{c_type(:ulong)} #{@name};\n"
  if polymorphic?
    result += "  #{c_type(:ulong)} #{@name}__class;\n"
  end
  result
end