Module: Riagent::Associations::ClassMethods

Defined in:
lib/riagent/associations.rb

Instance Method Summary collapse

Instance Method Details

#has_many(name, options = {}) ⇒ Object

Creates a has_many association

Parameters:

  • options (Hash) (defaults to: {})

    Association options

Options Hash (options):

  • :using (Symbol)

    The query type/mechanism for this association

  • :class (Symbol)

    Target class for the association



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/riagent/associations.rb', line 33

def has_many(name, options={})
  query_type = options[:using]
  target_class = options[:class]
  case query_type
  when :key_set
    has_many_using_key_set(name, target_class, options)
  when :solr
    has_many_using_solr(name, target_class, options)
  else
    raise ArgumentError, ":using query type not supported"
  end
end

#has_many_using_key_set(name, target_class, options) ⇒ Object

Creates a has_many association, where the collection will be loaded from an external crdt Set containing the child keys

Parameters:

  • name (String)

    Association name

  • target_class (Class)

    Target class

  • options (Hash)

    Association options (currently unused)



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/riagent/associations.rb', line 52

def has_many_using_key_set(name, target_class, options)
  # Create a <target name>_cache attribute accessors
  # These will be used to store the actual loaded collection
  target_cache_attribute = "#{name}_cache".to_sym
  attr_accessor target_cache_attribute
  
  # Create the getter method
  # Example: for 'has_many :posts', the getter method is :posts
  target_getter_method = "#{name}".to_sym

  define_method(target_getter_method) do
  end
  
  
  # Create the setter method=
  # Example: for 'has_many :posts', the setter method is :posts=
  target_setter_method = "#{name}=".to_sym

  define_method(target_setter_method) do | target |
  end
end

#has_many_using_solr(name, target_class, options) ⇒ Object

Creates a has_many association where the collection will be loaded via Solr queries.



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
# File 'lib/riagent/associations.rb', line 76

def has_many_using_solr(name, target_class, options)
  target_getter_method = "#{name}".to_sym
  
  # Create a <target name>_cache attribute accessors
  # These will be used to store the actual loaded collection
  target_cache_attribute = "#{name}_cache".to_sym
  attr_accessor target_cache_attribute
  
  # Create the getter method
  define_method(target_getter_method) do
    # First, check to see if the target collection has already been loaded/cached
#          cached_collection = send(target_cache_attribute)
#          if cached_collection.nil?
#            
#            source_key_value = send(:key)  # Get the source (parent) id
#            cached_collection = target_class.find(target_key)
#            send(target_setter_method, cached_collection)  # Cache the loaded target collection
#          end
#          cached_value
  end
  
  target_setter_method = "#{name}=".to_sym
  
  # Create the setter method=
  define_method(target_setter_method) do | target |
  end
end

#has_one(name, options = {}) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/riagent/associations.rb', line 104

def has_one(name, options={})
  target_key_attribute = "#{name}_key"
  target_class = options[:class]
  
  # Create a <target name>_key attribute, 
  attribute target_key_attribute, String, default: ''
  
  # Create a <target name>_cache attribute accessors
  # These will be used to store the actual instance of the target
  target_cache_attribute = "#{name}_cache".to_sym
  attr_accessor target_cache_attribute
    
  target_getter_method = "#{name}".to_sym
  target_setter_method = "#{name}=".to_sym
  
  # Create the setter method=
  define_method(target_setter_method) do | target |
    # Only assignments of the correct target class are allowed
    unless target.kind_of? target_class
      raise ArgumentError, "Invalid argument type #{target.class}, #{target_class} expected."
    end
    target_key = target ? target.key : nil
    attribute_setter = "#{target_key_attribute}=".to_sym
    send(attribute_setter, target_key)
    attribute_cache_getter = "#{target_cache_attribute}="
    send(attribute_cache_getter, target)
  end

  # Create the getter method
  define_method(target_getter_method) do
    # First, check to see if the target instance has already been loaded/cached
    cached_value = send(target_cache_attribute)
    if cached_value.nil?
      target_key = send(target_key_attribute)
      cached_value = target_class.find(target_key)
      send(target_setter_method, cached_value)  # Cache the loaded target instance
    end
    cached_value
  end
  
  # Create build_<target> method
  build_helper_method = "build_#{name}".to_sym
  define_method(build_helper_method) do | attributes |
    target_instance = target_class.new attributes
    target_instance.key = self.key # The target object gets the source's key by default
    send(target_setter_method, target_instance)
  end
end