Class: Arrest::AbstractResource

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming, ActiveModel::Translation
Includes:
ActiveModel::Conversion, ActiveModel::Dirty, ActiveModel::Validations, BelongsTo, HasAttributes
Defined in:
lib/arrest/abstract_resource.rb

Direct Known Subclasses

RestChild, RootResource

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes included from HasAttributes

#attribute_values

Class Method Summary collapse

Instance Method Summary collapse

Methods included from BelongsTo

included

Methods included from HasAttributes

#attributes, #attributes=, included, #init_from_hash, #initialize_has_attributes, #load_from_stub, #stubbed?, #to_hash, #to_jhash, #update_attributes

Constructor Details

#initialize(context, hash = {}, from_json = false) ⇒ AbstractResource

Returns a new instance of AbstractResource.



245
246
247
248
# File 'lib/arrest/abstract_resource.rb', line 245

def initialize(context, hash={}, from_json = false)
  @context = context
  initialize_has_attributes(hash, from_json)
end

Class Attribute Details

.scopesObject (readonly)

Returns the value of attribute scopes.



81
82
83
# File 'lib/arrest/abstract_resource.rb', line 81

def scopes
  @scopes
end

Instance Attribute Details

#contextObject

Returns the value of attribute context.



78
79
80
# File 'lib/arrest/abstract_resource.rb', line 78

def context
  @context
end

#idObject

Returns the value of attribute id.



243
244
245
# File 'lib/arrest/abstract_resource.rb', line 243

def id
  @id
end

Class Method Details

.all_filtersObject



231
232
233
234
235
236
237
238
# File 'lib/arrest/abstract_resource.rb', line 231

def all_filters
  all_filters = @filters
  all_filters ||= []
  if superclass.respond_to?('filters') && superclass.filters
    all_fields += superclass.filters
  end
  all_filters
end

.body_root(response) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
# File 'lib/arrest/abstract_resource.rb', line 95

def body_root(response)
  if response == nil
    raise Errors::DocumentNotFoundError
  end
  all = JSON.parse(response)
  body = all["result"]
  if body == nil
    raise Errors::DocumentNotFoundError
  end
  body
end

.build(context, hash) ⇒ Object



107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/arrest/abstract_resource.rb', line 107

def build(context, hash)
  resource = self.new(context, hash, true)

  # traverse fields for subresources and fill them in
  self.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
    ids = AbstractResource::source.get_many_other_ids(context, "#{resource.resource_location}/#{attr.sub_resource_field_name}")
    resource.send("#{attr.name}=", body_root(ids))
  end
  resource.clear_dirtiness()

  resource
end

.children(*args) ⇒ Object



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/arrest/abstract_resource.rb', line 188

def children(*args)
  method_name, options = args
  method_name = method_name.to_sym

  clazz_name = method_name.to_s
  if options
    clazz = options[:class_name]
    if clazz
      clazz_name = clazz.to_s
    end
  end

  send :define_method, method_name do
    @child_collections ||= {}
    @child_collections[method_name] ||= ChildCollection.new(self, (StringUtils.classify (StringUtils.singular clazz_name)))
    @child_collections[method_name]
  end
end

.create_has_many_attribute(sub_resource, ids_field_name, method_name, clazz_name, url_part, foreign_key, read_only) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/arrest/abstract_resource.rb', line 168

def create_has_many_attribute(sub_resource, ids_field_name, method_name,
                              clazz_name, url_part, foreign_key, read_only)
  if sub_resource
    define_attribute_methods [ids_field_name]
    return HasManySubResourceAttribute.new(ids_field_name,
                                           method_name,
                                           clazz_name,
                                           url_part,
                                           foreign_key,
                                           read_only)
  else
    return HasManyAttribute.new(ids_field_name,
                                method_name,
                                clazz_name,
                                url_part,
                                foreign_key,
                                read_only)
  end
end

.custom_resource_name(new_name) ⇒ Object



120
121
122
# File 'lib/arrest/abstract_resource.rb', line 120

def custom_resource_name(new_name)
  @custom_resource_name = new_name
end

.filtersObject



227
228
229
# File 'lib/arrest/abstract_resource.rb', line 227

def filters
  @filters
end

.has_many(*args) ⇒ Object



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/arrest/abstract_resource.rb', line 134

def has_many(*args)
  method_name, options = args
  ids_field_name = (StringUtils.singular(method_name.to_s) + '_ids').to_sym
  method_name = method_name.to_sym
  clazz_name = StringUtils.singular(method_name.to_s)
  foreign_key = clazz_name + "_id"
  sub_resource = false
  read_only = false
  if options
    clazz_name = options[:class_name].to_s unless options[:class_name] == nil
    foreign_key = "#{StringUtils.underscore(clazz_name)}_id"
    foreign_key = options[:foreign_key].to_s unless options[:foreign_key] == nil
    sub_resource = !!options[:sub_resource]
    read_only = options[:read_only]
  end

  url_part = method_name.to_s

  hm_attr = create_has_many_attribute(sub_resource, # e.g. 'team_ids' attribute for 'has_many :teams'
                                      ids_field_name,
                                      method_name,
                                      clazz_name,
                                      url_part,
                                      foreign_key,
                                      read_only)
  add_attribute(hm_attr)

  send :define_method, method_name do # e.g. define 'teams' method for notation 'has_many :teams'
    @has_many_collections ||= {}
    @has_many_collections[method_name] ||= HasManyCollection.new(self, hm_attr)
    @has_many_collections[method_name]
  end
end

.inherited(child) ⇒ Object



83
84
85
# File 'lib/arrest/abstract_resource.rb', line 83

def inherited(child)
  ScopedRoot::register_resource(child)
end

.mk_proxy(context_provider) ⇒ Object



87
88
89
# File 'lib/arrest/abstract_resource.rb', line 87

def mk_proxy(context_provider)
  ResourceProxy.new(self, context_provider)
end

.parent(*args) ⇒ Object



207
208
209
210
# File 'lib/arrest/abstract_resource.rb', line 207

def parent(*args)
  method_name = args[0].to_s.to_sym
  class_eval "def #{method_name}; self.parent; end"
end

.read_only_attributes(args) ⇒ Object



220
221
222
223
224
225
# File 'lib/arrest/abstract_resource.rb', line 220

def read_only_attributes(args)
  args.each_pair do |name, clazz|
    self.send :attr_accessor,name
    add_attribute(Attribute.new(name, true, clazz))
  end
end

.resource_nameObject



124
125
126
127
128
129
130
131
132
# File 'lib/arrest/abstract_resource.rb', line 124

def resource_name
  if @custom_resource_name
    @custom_resource_name
  else
    simple_name = ClassUtils.simple_name(self)
    usd_name = StringUtils.underscore(simple_name)
    StringUtils.plural(usd_name)
  end
end

.scope(name, options = {}, &block) ⇒ Object



212
213
214
215
216
217
# File 'lib/arrest/abstract_resource.rb', line 212

def scope(name, options = {}, &block)
  if @scopes == nil
    @scopes = []
  end
  @scopes << Scope.new(name, options, &block)
end

.sourceObject



91
92
93
# File 'lib/arrest/abstract_resource.rb', line 91

def source
  Arrest::Source::source
end

Instance Method Details

#==(comparison_object) ⇒ Object



305
306
307
308
309
# File 'lib/arrest/abstract_resource.rb', line 305

def == (comparison_object)
  other_class_name = comparison_object.class.name if comparison_object
  other_id = comparison_object.id if comparison_object
  self.class.name == other_class_name && self.id == other_id
end

#clear_dirtinessObject



250
251
252
# File 'lib/arrest/abstract_resource.rb', line 250

def clear_dirtiness
  @changed_attributes.clear if @changed_attributes
end

#curlObject

convenience method printing curl command



296
297
298
299
300
301
302
303
# File 'lib/arrest/abstract_resource.rb', line 296

def curl
  hs = ""
  Arrest::Source.header_decorator.headers.each_pair do |k,v|
    hs << " -H '#{k}:#{v}' "
  end

  "curl #{hs} -v '#{Arrest::Source.source.url}/#{self.resource_location}'"
end

#deleteObject



291
292
293
# File 'lib/arrest/abstract_resource.rb', line 291

def delete
  AbstractResource::source().delete(@context, self)
end

#new_record?Boolean

Returns:



287
288
289
# File 'lib/arrest/abstract_resource.rb', line 287

def new_record?
  [nil, ''].include?(id)
end

#reloadObject



280
281
282
283
284
285
# File 'lib/arrest/abstract_resource.rb', line 280

def reload
  @has_many_collections = {}
  @child_collections = {}
  hash = internal_reload
  self.attributes= hash
end

#saveObject



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/arrest/abstract_resource.rb', line 254

def save
  if Source.skip_validations || self.valid?
    req_type = new_record? ? :post : :put
    success = !!AbstractResource::source.send(req_type, @context, self)

    if success
      # check for sub resources in case of n:m relationships
      self.class.all_fields.find_all{|f| f.is_a?(HasManySubResourceAttribute)}.each do |attr|
        if !attr.sub_resource_read_only? && self.send("#{attr.name}_changed?") # check whether this 'subresource' attribute has been touched
          ids = self.send(attr.name) # get ids_field e.g. for team has_many :users get 'self.user_ids'
          srifn = attr.sub_resource_field_name
          result = !!AbstractResource::source.put_sub_resource(self, srifn, ids)
          return false if !result
        end
      end
      clear_dirtiness() # unset the dirtiness after saving (only used for HasManySubResourceAttributes), see ActiveModel::Dirty
      return true
    end
  end
  false
end

#save!Object



276
277
278
# File 'lib/arrest/abstract_resource.rb', line 276

def save!
  raise self.errors.inspect unless self.save
end