Module: NCore::Associations

Defined in:
lib/ncore/associations.rb

Instance Method Summary collapse

Instance Method Details

#belongs_to(assoc_name, association_key: nil, class_name: nil) ⇒ Object

assoc_name - singular association name :association_key - key on this resource used to reference the parent association

defaults to `assoc_name+'_id'`

:class_name - Module::Class of the parent association, as a string



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

def belongs_to(assoc_name, association_key: nil, class_name: nil)
  assoc_name = assoc_name.to_s
  parent_key = association_key&.to_s || "#{assoc_name}_id"
  klass      = class_name || "#{module_name}::#{assoc_name.camelize}"

  # attr :parent_id
  # def parent({})
  class_eval <<-P1, __FILE__, __LINE__+1
    attr :#{parent_key}
    def #{assoc_name}(params={})
      return nil unless #{parent_key}
      params = parse_request_params(params).reverse_merge credentials: api_creds
      if params.except(:credentials, :request).empty?
        # only cache unfiltered, default api call
        @attribs[:#{assoc_name}] ||= #{klass}.find(#{parent_key}, params)
      else
        #{klass}.find(#{parent_key}, params)
      end
    end
  P1

  class_eval <<-P2, __FILE__, __LINE__+1
    def #{parent_key}=(v)
      @attribs[:#{assoc_name}] = nil unless @attribs[:#{parent_key}] == v
      @attribs[:#{parent_key}] = v
    end
    private :#{parent_key}=
  P2
end

#has_many(assoc_name, association_key: nil, class_name: nil) ⇒ Object

assoc_name - plural association name :association_key - key used by the association to reference the parent

defaults to `attrib_name+'_id'`

:class_name - Module::Class of the child association, as a string



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

def has_many(assoc_name, association_key: nil, class_name: nil)
  assoc_name = assoc_name.to_s
  parent_key = association_key&.to_s || "#{attrib_name}_id"
  klass      = class_name || "#{module_name}::#{assoc_name.camelize.singularize}"

  # def items({})
  class_eval <<-A1, __FILE__, __LINE__+1
    def #{assoc_name}(params={})
      return [] unless id
      reload = params.delete :reload
      cacheable = params.except(:credentials, :request).empty?
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      if cacheable
        # only cache unfiltered, default api call
        @attribs[:#{assoc_name}] = (!reload && @attribs[:#{assoc_name}]) || #{klass}.all(params)
      else
        #{klass}.all(params)
      end
    end
  A1

  # def find_item(id, {})
  class_eval <<-F1, __FILE__, __LINE__+1
    def find_#{assoc_name.singularize}(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.find(aid, params)
    end
  F1

  # def retrieve_item(id, {})
  class_eval <<-F2, __FILE__, __LINE__+1
    def retrieve_#{assoc_name.singularize}(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.retrieve(aid, params)
    end
  F2

  # def create_item({})
  # will always return the object; check .errors? or .valid? to see how it went
  class_eval <<-C1, __FILE__, __LINE__+1
    def create_#{assoc_name.singularize}(params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.create(params)
    end
  C1

  # def create_item!({})
  class_eval <<-C2, __FILE__, __LINE__+1
    def create_#{assoc_name.singularize}!(params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.create!(params)
    end
  C2

  # def update_item(id, {})
  # will always return the object; check .errors? or .valid? to see how it went
  class_eval <<-U1, __FILE__, __LINE__+1
    def update_#{assoc_name.singularize}(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.update(aid, params)
    end
  U1

  # def update_item!(id, {})
  class_eval <<-U2, __FILE__, __LINE__+1
    def update_#{assoc_name.singularize}!(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.update!(aid, params)
    end
  U2

  # def delete_item(id, {})
  # will always return the object; check .errors? or .valid? to see how it went
  class_eval <<-D1, __FILE__, __LINE__+1
    def delete_#{assoc_name.singularize}(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.delete(aid, params)
    end
  D1

  # def delete_item!(id, {})
  class_eval <<-D2, __FILE__, __LINE__+1
    def delete_#{assoc_name.singularize}!(aid, params={})
      raise UnsavedObjectError unless id
      params = parse_request_params(params).reverse_merge credentials: api_creds
      params[:#{parent_key}] = id
      #{klass}.delete!(aid, params)
    end
  D2
end