Module: JsonapiCompliable::Adapters::ActiveRecordSideloading

Defined in:
lib/jsonapi_compliable/adapters/active_record_sideloading.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/jsonapi_compliable/adapters/active_record_sideloading.rb', line 27

def belongs_to(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk)
  _scope = scope

  allow_sideload association_name, type: :belongs_to, resource: resource, foreign_key: foreign_key, primary_key: primary_key do
    scope do |parents|
      parent_ids = parents.map { |p| p.send(foreign_key) }
      _scope.call.where(primary_key => parent_ids.uniq.compact)
    end

    assign do |parents, children|
      parents.each do |parent|
        relevant_child = children.find { |c| parent.send(foreign_key) == c.send(primary_key) }
        parent.send(:#{association_name}=", relevant_child)
      end
    end

    instance_eval(&blk) if blk
  end
end

#has_and_belongs_to_many(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, as: nil, &blk) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/jsonapi_compliable/adapters/active_record_sideloading.rb', line 69

def has_and_belongs_to_many(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, as: nil, &blk)
  through = foreign_key.keys.first
  fk      = foreign_key.values.first
  _scope  = scope

  allow_sideload association_name, type: :habtm, foreign_key: foreign_key, primary_key: primary_key, resource: resource do
    scope do |parents|
      parent_ids = parents.map { |p| p.send(primary_key) }
      parent_ids.uniq!
      parent_ids.compact!
      _scope.call.joins(through).where(through => { fk => parent_ids }).distinct
    end

    assign do |parents, children|
      parents.each do |parent|
        parent.association(association_name).loaded!
        relevant_children = children.select { |c| c.send(through).any? { |ct| ct.send(fk) == parent.send(primary_key) } }
        relevant_children.each do |c|
          parent.association(association_name).add_to_target(c, :skip_callbacks)
        end
      end
    end

    instance_eval(&blk) if blk
  end
end

#has_many(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/jsonapi_compliable/adapters/active_record_sideloading.rb', line 4

def has_many(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk)
  _scope = scope

  allow_sideload association_name, type: :has_many, resource: resource, foreign_key: foreign_key, primary_key: primary_key do
    scope do |parents|
      parent_ids = parents.map { |p| p.send(primary_key) }
      _scope.call.where(foreign_key => parent_ids.uniq.compact)
    end

    assign do |parents, children|
      parents.each do |parent|
        parent.association(association_name).loaded!
        relevant_children = children.select { |c| c.send(foreign_key) == parent.send(primary_key) }
        relevant_children.each do |c|
          parent.association(association_name).add_to_target(c, :skip_callbacks)
        end
      end
    end

    instance_eval(&blk) if blk
  end
end

#has_one(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/jsonapi_compliable/adapters/active_record_sideloading.rb', line 47

def has_one(association_name, scope: nil, resource:, foreign_key:, primary_key: :id, &blk)
  _scope = scope

  allow_sideload association_name, type: :has_one, foreign_key: foreign_key, primary_key: primary_key, resource: resource do
    scope do |parents|
      parent_ids = parents.map { |p| p.send(primary_key) }
      _scope.call.where(foreign_key => parent_ids.uniq.compact)
    end

    assign do |parents, children|
      parents.each do |parent|
        parent.association(association_name).loaded!
        relevant_child = children.find { |c| c.send(foreign_key) == parent.send(primary_key) }
        next unless relevant_child
        parent.association(association_name).replace(relevant_child, false)
      end
    end

    instance_eval(&blk) if blk
  end
end

#polymorphic_belongs_to(association_name, group_by:, groups:, &blk) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/jsonapi_compliable/adapters/active_record_sideloading.rb', line 96

def polymorphic_belongs_to(association_name, group_by:, groups:, &blk)
  allow_sideload association_name, type: :polymorphic_belongs_to, polymorphic: true do
    group_by(group_by)

    groups.each_pair do |type, config|
      primary_key = config[:primary_key] || :id
      foreign_key = config[:foreign_key]

      allow_sideload type, parent: self, primary_key: primary_key, foreign_key: foreign_key, type: :belongs_to, resource: config[:resource] do
        scope do |parents|
          parent_ids = parents.map { |p| p.send(foreign_key) }
          parent_ids.compact!
          parent_ids.uniq!
          config[:scope].call.where(primary_key => parent_ids)
        end

        assign do |parents, children|
          parents.each do |parent|
            parent.send(:#{association_name}=", children.find { |c| c.send(primary_key) == parent.send(foreign_key) })
          end
        end
      end
    end
  end

  instance_eval(&blk) if blk
end