Module: Neoid::Relationship

Defined in:
lib/neoid/relationship.rb

Defined Under Namespace

Modules: ClassMethods, InstanceMethods Classes: RelationshipLazyProxy

Class Method Summary collapse

Class Method Details

.from_hash(hash) ⇒ Object



4
5
6
7
8
# File 'lib/neoid/relationship.rb', line 4

def from_hash(hash)
  relationship = RelationshipLazyProxy.new(hash)

  relationship
end

.included(receiver) ⇒ Object



10
11
12
13
14
15
16
17
18
# File 'lib/neoid/relationship.rb', line 10

def included(receiver)
  receiver.send :include, Neoid::ModelAdditions
  receiver.send :include, InstanceMethods
  receiver.extend         ClassMethods

  initialize_relationship receiver if Neoid.env_loaded

  Neoid.relationship_models << receiver
end

.initialize_relationship(rel_model) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/neoid/relationship.rb', line 24

def initialize_relationship(rel_model)
  rel_model.reflect_on_all_associations(:belongs_to).each do |belongs_to|
    return if belongs_to.options[:polymorphic]

    # e.g. all has_many on User class
    all_has_many = belongs_to.klass.reflect_on_all_associations(:has_many)

    # has_many (without through) on the side of the relationship that removes a relationship. e.g. User has_many :likes
    this_has_many = all_has_many.find { |o| o.klass == rel_model }
    next unless this_has_many

    # e.g. User has_many :likes, after_remove: ...
    full_callback_name = "after_remove_for_#{this_has_many.name}"
    belongs_to.klass.send(full_callback_name) << :neo_after_relationship_remove if belongs_to.klass.method_defined?(full_callback_name)

    # has_many (with through) on the side of the relationship that removes a relationship. e.g. User has_many :movies, through :likes
    many_to_many = all_has_many.find { |o| o.options[:through] == this_has_many.name }
    next unless many_to_many

    return if many_to_many.options[:as] # polymorphic are not supported here yet

    # user_id
    foreign_key_of_owner = many_to_many.through_reflection.foreign_key

    # movie_id
    foreign_key_of_record = many_to_many.source_reflection.foreign_key

    (Neoid::Relationship. ||= {}).tap do |data|
      (data[belongs_to.klass.name.to_s] ||= {}).tap do |model_data|
        model_data[many_to_many.klass.name.to_s] = [rel_model.name.to_s, foreign_key_of_owner, foreign_key_of_record]
      end
    end

    # e.g. User has_many :movies, through: :likes, before_remove: ...
    full_callback_name = "before_remove_for_#{many_to_many.name}"
    belongs_to.klass.send(full_callback_name) << :neo_before_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)

    # e.g. User has_many :movies, through: :likes, after_remove: ...
    full_callback_name = "after_remove_for_#{many_to_many.name}"
    belongs_to.klass.send(full_callback_name) << :neo_after_relationship_through_remove if belongs_to.klass.method_defined?(full_callback_name)
  end
end

.meta_dataObject



20
21
22
# File 'lib/neoid/relationship.rb', line 20

def 
  @meta_data ||= {}
end