-
Notifications
You must be signed in to change notification settings - Fork 534
/
Copy pathrelationship.rb
122 lines (104 loc) · 3.64 KB
/
relationship.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
66
67
68
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
95
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
module JSONAPI
class Relationship
attr_reader :acts_as_set, :foreign_key, :options, :name,
:class_name, :polymorphic, :always_include_linkage_data,
:parent_resource, :eager_load_on_include, :custom_methods,
:inverse_relationship
def initialize(name, options = {})
@name = name.to_s
@options = options
@acts_as_set = options.fetch(:acts_as_set, false) == true
@foreign_key = options[:foreign_key] ? options[:foreign_key].to_sym : nil
@parent_resource = options[:parent_resource]
@relation_name = options.fetch(:relation_name, @name)
@custom_methods = options.fetch(:custom_methods, {})
@polymorphic = options.fetch(:polymorphic, false) == true
@polymorphic_relations = options[:polymorphic_relations]
@always_include_linkage_data = options.fetch(:always_include_linkage_data, false) == true
@eager_load_on_include = options.fetch(:eager_load_on_include, true) == true
end
alias_method :polymorphic?, :polymorphic
def primary_key
@primary_key ||= resource_klass._primary_key
end
def resource_klass
@resource_klass ||= @parent_resource.resource_klass_for(@class_name)
end
def table_name
@table_name ||= resource_klass._table_name
end
def self.polymorphic_types(name)
@poly_hash ||= {}.tap do |hash|
ObjectSpace.each_object do |klass|
next unless Module === klass
if ActiveRecord::Base > klass
klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection|
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
end
klass.reflect_on_all_associations(:has_one).select{|r| r.options[:as] }.each do |reflection|
(hash[reflection.options[:as]] ||= []) << klass.name.downcase
end
end
end
end
@poly_hash[name.to_sym]
end
def polymorphic_relations
@polymorphic_relations ||= self.class.polymorphic_types(@relation_name)
end
def type
@type ||= resource_klass._type.to_sym
end
def relation_name(options)
case @relation_name
when Symbol
# :nocov:
@relation_name
# :nocov:
when String
@relation_name.to_sym
when Proc
@relation_name.call(options)
end
end
def belongs_to?
false
end
def readonly?
@options[:readonly]
end
def redefined_pkey?
belongs_to? && primary_key != resource_klass._default_primary_key
end
class ToOne < Relationship
attr_reader :foreign_key_on
def initialize(name, options = {})
super
@class_name = options.fetch(:class_name, name.to_s.camelize)
@foreign_key ||= "#{name}_id".to_sym
@foreign_key_on = options.fetch(:foreign_key_on, :self)
if parent_resource
@inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type)
end
end
def belongs_to?
foreign_key_on == :self
end
def polymorphic_type
"#{name}_type" if polymorphic?
end
end
class ToMany < Relationship
attr_reader :reflect
def initialize(name, options = {})
super
@class_name = options.fetch(:class_name, name.to_s.camelize.singularize)
@foreign_key ||= "#{name.to_s.singularize}_ids".to_sym
@reflect = options.fetch(:reflect, true) == true
if parent_resource
@inverse_relationship = options.fetch(:inverse_relationship, parent_resource._type.to_s.singularize.to_sym)
end
end
end
end
end