Class: MassiveRecord::ORM::Relations::Proxy::ReferencesMany

Inherits:
MassiveRecord::ORM::Relations::Proxy show all
Defined in:
lib/massive_record/orm/relations/proxy/references_many.rb

Instance Attribute Summary

Attributes inherited from MassiveRecord::ORM::Relations::Proxy

#metadata, #proxy_owner, #proxy_target

Instance Method Summary collapse

Methods inherited from MassiveRecord::ORM::Relations::Proxy

#initialize, #inspect, #loaded!, #loaded?, #method_missing, #reload, #respond_to?, #to_param

Constructor Details

This class inherits a constructor from MassiveRecord::ORM::Relations::Proxy

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class MassiveRecord::ORM::Relations::Proxy

Instance Method Details

#<<(*records) ⇒ Object Also known as: push, concat

Adding record(s) to the collection.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 45

def <<(*records)
  save_records = proxy_owner.persisted?

  if records.flatten.all? &:valid?
    records.flatten.each do |record|
      unless include? record
        raise_if_type_mismatch(record)
        add_foreign_key_in_proxy_owner(record.id)
        proxy_target << record
        record.save if save_records
      end
    end

    proxy_owner.save if save_records

    self
  end
end

#delete(*records) ⇒ Object

Deletes record(s) from the collection



77
78
79
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 77

def delete(*records)
  delete_or_destroy *records, :delete
end

#delete_allObject

Deletes all records from the relationship. Does not destroy the records



94
95
96
97
98
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 94

def delete_all
  delete(load_proxy_target)
  reset
  loaded!
end

#destroy(*records) ⇒ Object

Destroy record(s) from the collection Each record will be asked to destroy itself as well



70
71
72
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 70

def destroy(*records)
  delete_or_destroy *records, :destroy
end

#destroy_allObject

Destroys all records



84
85
86
87
88
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 84

def destroy_all
  destroy(load_proxy_target)
  reset
  loaded!
end

#empty?Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 124

def empty?
  length == 0
end

#find(id) ⇒ Object

Raises:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 132

def find(id)
  if loaded?
    record = proxy_target.find { |record| record.id == id }
  elsif find_with_proc?
    if id.starts_with? proxy_owner.send(.records_starts_from)
      record = proxy_target_class.find(id)
    end
  elsif foreign_key_in_proxy_owner_exists?(id)
    record = proxy_target_class.find(id)
  end

  raise RecordNotFound.new("Could not find #{proxy_target_class.model_name} with id=#{id}") if record.nil?

  record
end

#firstObject



128
129
130
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 128

def first
  limit(1).first
end

#include?(record) ⇒ Boolean

Checks if record is included in collection

TODO This needs a bit of work, depending on if proxy’s proxy_target

has been loaded or not. For now, we are just checking
what we currently have in @proxy_target

Returns:

  • (Boolean)


107
108
109
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 107

def include?(record)
  load_proxy_target.include? record
end

#lengthObject Also known as: count, size

Returns the length of targes

TODO This can be smarter as well. For instance; if we have not

loaded targets, and we have foreign keys in the owner we
can simply do a owner's foreign keys and ask for it's length.


118
119
120
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 118

def length
  load_proxy_target.length
end

#limit(limit) ⇒ Object

Returns a limited result set of target records.

TODO If we know all our foreign keys (basically we also know our length)

we can then mark our self as loaded if limit is equal to or greater
than foreign keys length.


155
156
157
158
159
160
161
162
163
164
165
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 155

def limit(limit)
  if loaded?
    proxy_target.slice(0, limit)
  elsif find_with_proc?
    find_proxy_target_with_proc(:limit => limit)
  else
    ids = proxy_owner.send(.foreign_key).slice(0, limit)
    ids = ids.first if ids.length == 1
    [find_proxy_target(ids)].flatten
  end
end

#load_proxy_targetObject

Loading proxy_targets will merge it with records found currently in proxy, to make sure we don’t remove any pushed proxy_targets only cause we load the proxy_targets.

TODO - Implement methods like:

  * find_in_batches
  * find_each
  * etc :-)

- A counter cache is also nice.


18
19
20
21
22
23
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 18

def load_proxy_target
  proxy_target_before_load = proxy_target
  proxy_target_after_load = super

  self.proxy_target = (proxy_target_before_load + proxy_target_after_load).uniq
end

#replace(*records) ⇒ Object



30
31
32
33
34
35
36
37
38
39
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 30

def replace(*records)
  records.flatten!

  if records.length == 1 and records.first.nil?
    reset
  else
    delete_all
    concat(records)
  end
end

#resetObject



25
26
27
28
# File 'lib/massive_record/orm/relations/proxy/references_many.rb', line 25

def reset
  super
  @proxy_target = []
end