Class: Parse::Object
- Extended by:
- Core::Querying, Core::Schema
- Includes:
- Associations::BelongsTo, Associations::HasMany, Associations::HasOne, Core::Actions, Core::Fetching, Properties
- Defined in:
- lib/parse/model/object.rb,
lib/parse/webhooks.rb
Overview
This is the core class for all app specific Parse table subclasses. This class in herits from Parse::Pointer since an Object is a Parse::Pointer with additional fields, at a minimum, created_at, updated_at and ACLs. This class also handles all the relational types of associations in a Parse application and handles the main CRUD operations.
As the parent class to all custom subclasses, this class provides the default property schema:
class Parse::Object
# All subclasses will inherit these properties by default.
# the objectId column of a record.
property :id, :string, field: :objectId
# The the last updated date for a record (Parse::Date)
property :updated_at, :date
# The original creation date of a record (Parse::Date)
property :created_at, :date
# The Parse::ACL field
property :acl, :acl, field: :ACL
end
Most Pointers and Object subclasses are treated the same. Therefore, defining a class Artist < Parse::Object that only has `id` set, will be treated as a pointer. Therefore a Parse::Object can be in a “pointer” state based on the data that it contains. Becasue of this, it is possible to take a Artist instance (in this example), that is in a pointer state, and fetch the rest of the data for that particular record without having to create a new object. Doing so would now mark it as not being a pointer anymore. This is important to the understanding on how relations and properties are handled.
The implementation of this class is large and has been broken up into several modules.
Properties:
All columns in a Parse object are considered a type of property (ex. string, numbers, arrays, etc) except in two cases - Pointers and Relations. For a detailed discussion of properties, see The Defining Properties section.
Associations:
Parse supports a three main types of relational associations. One type of relation is the `One-to-One` association. This is implemented through a specific column in Parse with a Pointer data type. This pointer column, contains a local value that refers to a different record in a separate Parse table. This association is implemented using the `:belongs_to` feature. The second association is of `One-to-Many`. This is implemented is in Parse as a Array type column that contains a list of of Parse pointer objects. It is recommended by Parse that this array does not exceed 100 items for performance reasons. This feature is implemented using the `:has_many` operation with the plural name of the local Parse class. The last association type is a Parse Relation. These can be used to implement a large `Many-to-Many` association without requiring an explicit intermediary Parse table or class. This feature is also implemented using the `:has_many` method but passing the option of `:relation`.
Direct Known Subclasses
Constant Summary
Constants included from Properties
Properties::BASE, Properties::BASE_FIELD_MAP, Properties::BASE_KEYS, Properties::CORE_FIELDS, Properties::DELETE_OP, Properties::TYPES
Constants inherited from Pointer
Constants inherited from Model
Model::CLASS_INSTALLATION, Model::CLASS_PRODUCT, Model::CLASS_ROLE, Model::CLASS_SESSION, Model::CLASS_USER, Model::ID, Model::KEY_CLASS_NAME, Model::KEY_CREATED_AT, Model::KEY_OBJECT_ID, Model::KEY_UPDATED_AT, Model::OBJECT_ID, Model::TYPE_ACL, Model::TYPE_BYTES, Model::TYPE_DATE, Model::TYPE_FIELD, Model::TYPE_FILE, Model::TYPE_GEOPOINT, Model::TYPE_NUMBER, Model::TYPE_OBJECT, Model::TYPE_POINTER, Model::TYPE_RELATION
Class Attribute Summary collapse
- .default_acls ⇒ Parse::ACL readonly
The set of default ACLs to be applied on newly created instances of this class.
- .parse_class(remoteName = nil) ⇒ String
The class method to override the implicitly assumed Parse collection name in your Parse database.
Instance Attribute Summary collapse
- #acl ⇒ ACL
The access control list (permissions) object for this record.
- #created_at ⇒ Date
The created_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
- #id ⇒ String
The value of Parse “objectId” field.
- #updated_at ⇒ Date
The updated_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
Class Method Summary collapse
- .build(json, table = nil) ⇒ Parse::Object
Method used for decoding JSON objects into their corresponding Object subclasses.
- .pointer(id) ⇒ Parse::Pointer
Helper method to create a Parse::Pointer object for a given id.
- .set_default_acl(id, read: false, write: false, role: false) ⇒ Object
A method to set default ACLs to be applied for newly created instances of this class.
- .webhook(type, block = nil) { ... } ⇒ OpenStruct
Register a webhook trigger or function for this subclass.
- .webhook_function(functionName, block = nil) { ... } ⇒ OpenStruct
Register a webhook function for this subclass.
Instance Method Summary collapse
- #[](key) ⇒ Object
Access the value for a defined property through hash accessor.
- #[]=(key, value) ⇒ Object
Set the value for a specific property through a hash accessor.
- #__type ⇒ Model::TYPE_OBJECT
- #after_create { ... } ⇒ Object
A callback called after the object has been created.
- #after_destroy { ... } ⇒ Object
A callback called after the object has been successfully deleted.
- #after_save { ... } ⇒ Object
A callback called after the object has been successfully saved.
- #apply_defaults! ⇒ Array
force apply default values for any properties defined with default values.
- #as_json(opts = nil) ⇒ Hash
A json-hash representing this object.
- #before_create { ... } ⇒ Object
A callback called before the object has been created.
- #before_destroy { ... } ⇒ Object
A callback called before the object is about to be deleted.
- #before_save { ... } ⇒ Object
A callback called before the object is saved.
- #clear_attribute_change!(atts) ⇒ Object
clear all change and dirty tracking information.
- #clear_changes! ⇒ Object
clears all dirty tracking information.
- #existed? ⇒ Boolean
Existed returns true if the object had existed before *its last save operation*.
- #initialize(opts = {}) ⇒ Parse::Object constructor
The main constructor for subclasses.
- #new? ⇒ Boolean
An object is considered new if it has no id.
- #parse_class ⇒ String (also: #className)
The Parse class for this object.
- #persisted? ⇒ Boolean
Determines if this object has been saved to the Parse database.
- #pretty ⇒ String
A pretty-formatted JSON string.
- #reload!(opts = {}) ⇒ Object
force reload from the database and replace any local fields with data from the persistent store.
- #rollback! ⇒ Object
Locally restores the previous state of the object and clears all dirty tracking information.
- #schema ⇒ Hash
The schema structure for this Parse collection from the server.
- #twin ⇒ Parse::Object
This method creates a new object of the same instance type with a copy of all the properties of the current instance.
- #updates(include_all = false) ⇒ Hash
Returns a hash of all the changes that have been made to the object.
- #validate! ⇒ self
Overrides ActiveModel::Validations#validate! instance method.
Methods included from Core::Querying
all, count, distinct, each, find, first, literal_where, newest, oldest, query, scope
Methods included from Core::Schema
auto_upgrade!, create_schema, fetch_schema, update_schema
Methods included from Core::Actions
#change_requests, #changes_applied!, #changes_payload, #create, #destroy, #destroy_request, #op_add!, #op_add_relation!, #op_add_unique!, #op_destroy!, #op_increment!, #op_remove!, #op_remove_relation!, #operate_field!, #prepare_save!, #relation_change_operations, #save, #save!, #set_attributes!, #update, #update!, #update_relations, #uri_path
Methods included from Core::Fetching
Methods included from Associations::HasMany
has_many, #relation_changes?, #relation_updates, #relations
Methods included from Associations::BelongsTo
Methods included from Associations::HasOne
Methods included from Properties
#apply_attributes!, #attribute_changes?, #attribute_updates, #attributes, #attributes=, #field_map, #fields, #format_operation, #format_value
Methods inherited from Pointer
#==, #attributes, #fetch, #fetched?, #hash, #json_hash, #pointer, #pointer?, #present?, #sig
Methods inherited from Model
Methods included from Client::Connectable
Constructor Details
#new(id) ⇒ Parse::Object #new(hash = {}) ⇒ Parse::Object
Should only be called with Parse::Object subclasses.
The main constructor for subclasses. It can take different parameter types including a String and a JSON hash. Assume a `Post` class that inherits from Parse::Object:
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | # File 'lib/parse/model/object.rb', line 298 def initialize(opts = {}) if opts.is_a?(String) #then it's the objectId @id = opts.to_s elsif opts.is_a?(Hash) #if the objectId is provided we will consider the object pristine #and not track dirty items dirty_track = opts[Parse::Model::OBJECT_ID] || opts[:objectId] || opts[:id] apply_attributes!(opts, dirty_track: !dirty_track) end # if no ACLs, then apply the class default acls # ACL.typecast will auto convert of Parse::ACL self.acl = self.class.default_acls.as_json if self.acl.nil? clear_changes! if @id.present? #then it was an import # do not apply defaults on a pointer because it will stop it from being # a pointer and will cause its field to be autofetched (for sync) apply_defaults! unless pointer? # do not call super since it is Pointer subclass end |
Class Attribute Details
.default_acls ⇒ Parse::ACL (readonly)
The set of default ACLs to be applied on newly created instances of this class. By default, public read and write are enabled.
215 216 217 | # File 'lib/parse/model/object.rb', line 215 def default_acls @default_acls end |
.parse_class(remoteName = nil) ⇒ String
The class method to override the implicitly assumed Parse collection name in your Parse database. The default Parse collection name is the singular form of the ruby Parse::Object subclass name. The Parse class value should match to the corresponding remote table in your database in order to properly store records and perform queries.
205 206 207 | # File 'lib/parse/model/object.rb', line 205 def parse_class @parse_class end |
Instance Attribute Details
#acl ⇒ ACL
Returns the access control list (permissions) object for this record.
504 505 506 | # File 'lib/parse/model/object.rb', line 504 def acl @acl end |
#created_at ⇒ Date
Returns the created_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
496 497 498 | # File 'lib/parse/model/object.rb', line 496 def created_at @created_at end |
#id ⇒ String
Returns the value of Parse “objectId” field.
492 | # File 'lib/parse/model/object.rb', line 492 property :id, field: :objectId |
#updated_at ⇒ Date
Returns the updated_at date of the record in UTC Zulu iso 8601 with 3 millisecond format.
500 501 502 | # File 'lib/parse/model/object.rb', line 500 def updated_at @updated_at end |
Class Method Details
.build(json, table = nil) ⇒ Parse::Object
If a Parse class object hash is encoutered for which we don't have a corresponding Parse::Object subclass for, a Parse::Pointer will be returned instead.
Method used for decoding JSON objects into their corresponding Object subclasses. The first parameter is a hash containing the object data and the second parameter is the name of the table / class if it is known. If it is not known, we we try and determine it by checking the “className” or :className entries in the hash.
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | # File 'lib/parse/model/object.rb', line 464 def self.build(json, table = nil) className = table className ||= (json[Parse::Model::KEY_CLASS_NAME] || json[:className]) if json.is_a?(Hash) if json.is_a?(Hash) && json["error"].present? && json["code"].present? warn "[Parse::Object] Detected object hash with 'error' and 'code' set. : #{json}" end className = parse_class unless parse_class == BASE_OBJECT_CLASS return if className.nil? # we should do a reverse lookup on who is registered for a different class type # than their name with parse_class klass = Parse::Model.find_class className o = nil if klass.present? # when creating objects from Parse JSON data, don't use dirty tracking since # we are considering these objects as "pristine" o = klass.new(json) else o = Parse::Pointer.new className, (json[Parse::Model::OBJECT_ID] || json[:objectId]) end return o # rescue NameError => e # puts "Parse::Object.build constant class error: #{e}" # rescue Exception => e # puts "Parse::Object.build error: #{e}" end |
.pointer(id) ⇒ Parse::Pointer
Helper method to create a Parse::Pointer object for a given id.
331 332 333 334 | # File 'lib/parse/model/object.rb', line 331 def self.pointer(id) return nil if id.nil? Parse::Pointer.new self.parse_class, id end |
.set_default_acl(id, read: false, write: false, role: false) ⇒ Object
A method to set default ACLs to be applied for newly created instances of this class. All subclasses have public read and write enabled by default.
243 244 245 246 247 248 | # File 'lib/parse/model/object.rb', line 243 def set_default_acl(id, read: false, write: false, role: false) unless id.present? raise ArgumentError, "Invalid argument applying #{self}.default_acls : must be either objectId, role or :public" end role ? default_acls.apply_role(id, read, write) : default_acls.apply(id, read, write) end |
.webhook(type, block = nil) { ... } ⇒ OpenStruct
Register a webhook trigger or function for this subclass.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | # File 'lib/parse/webhooks.rb', line 56 def self.webhook(type, block = nil) if type == :function unless block.is_a?(String) || block.is_a?(Symbol) raise ArgumentError, "Invalid Cloud Code function name: #{block}" end Parse::Webhooks.route(:function, block, &Proc.new) # then block must be a symbol or a string else if block_given? Parse::Webhooks.route(type, self, &Proc.new) else Parse::Webhooks.route(type, self, block) end end #if block end |
.webhook_function(functionName, block = nil) { ... } ⇒ OpenStruct
Register a webhook function for this subclass.
32 33 34 35 36 37 38 39 40 | # File 'lib/parse/webhooks.rb', line 32 def self.webhook_function(functionName, block = nil) if block_given? Parse::Webhooks.route(:function, functionName, &Proc.new) else block = functionName.to_s.underscore.to_sym if block.blank? block = method(block.to_sym) if block.is_a?(Symbol) Parse::Webhooks.route(:function, functionName, block) end end |
Instance Method Details
#[](key) ⇒ Object
Access the value for a defined property through hash accessor. This method returns nil if the key is not one of the defined properties for this Parse::Object subclass.
511 512 513 514 | # File 'lib/parse/model/object.rb', line 511 def [](key) return nil unless self.class.fields[key.to_sym].present? send(key) end |
#[]=(key, value) ⇒ Object
Set the value for a specific property through a hash accessor. This method does nothing if key is not one of the defined properties for this Parse::Object subclass.
522 523 524 525 | # File 'lib/parse/model/object.rb', line 522 def []=(key, value) return unless self.class.fields[key.to_sym].present? send("#{key}=", value) end |
#__type ⇒ Model::TYPE_OBJECT
141 | # File 'lib/parse/model/object.rb', line 141 def __type; Parse::Model::TYPE_OBJECT; end |
#after_create { ... } ⇒ Object
A callback called after the object has been created.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#after_destroy { ... } ⇒ Object
This is not related to a Parse afterDelete webhook trigger.
A callback called after the object has been successfully deleted.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#after_save { ... } ⇒ Object
This is not related to a Parse afterSave webhook trigger.
A callback called after the object has been successfully saved.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#apply_defaults! ⇒ Array
force apply default values for any properties defined with default values.
322 323 324 325 326 | # File 'lib/parse/model/object.rb', line 322 def apply_defaults! self.class.defaults_list.each do |key| send(key) # should call set default proc/values if nil end end |
#as_json(opts = nil) ⇒ Hash
Returns a json-hash representing this object.
271 272 273 274 275 | # File 'lib/parse/model/object.rb', line 271 def as_json(opts = nil) return pointer if pointer? changed_fields = changed_attributes super(opts).delete_if { |k, v| v.nil? && !changed_fields.has_key?(k) } end |
#before_create { ... } ⇒ Object
A callback called before the object has been created.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#before_destroy { ... } ⇒ Object
This is not related to a Parse beforeDelete webhook trigger.
A callback called before the object is about to be deleted.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#before_save { ... } ⇒ Object
This is not related to a Parse beforeSave webhook trigger.
A callback called before the object is saved.
175 | # File 'lib/parse/model/object.rb', line 175 define_model_callbacks :create, :save, :destroy, only: [:after, :before] |
#clear_attribute_change!(atts) ⇒ Object
clear all change and dirty tracking information.
441 442 443 | # File 'lib/parse/model/object.rb', line 441 def clear_attribute_change!(atts) clear_attribute_changes(atts) end |
#clear_changes! ⇒ Object
clears all dirty tracking information
354 355 356 | # File 'lib/parse/model/object.rb', line 354 def clear_changes! clear_changes_information end |
#existed? ⇒ Boolean
You should not use this method inside a beforeSave webhook.
Existed returns true if the object had existed before *its last save operation*. This method returns false if the #created_at and #updated_at dates of an object are equal, implyiny this object has been newly created and saved (especially in an afterSave hook).
This is a helper method in a webhook afterSave to know if this object was recently saved in the beforeSave webhook. Checking for #existed? == false in an afterSave hook, is equivalent to using #new? in a beforeSave hook.
376 377 378 379 380 381 | # File 'lib/parse/model/object.rb', line 376 def existed? if @id.blank? || @created_at.blank? || @updated_at.blank? return false end created_at != updated_at end |
#new? ⇒ Boolean
An object is considered new if it has no id. This is the method to use in a webhook beforeSave when checking if this object is new.
361 362 363 | # File 'lib/parse/model/object.rb', line 361 def new? @id.blank? end |
#parse_class ⇒ String Also known as: className
Returns the Parse class for this object.
258 259 260 | # File 'lib/parse/model/object.rb', line 258 def parse_class self.class.parse_class end |
#persisted? ⇒ Boolean
Determines if this object has been saved to the Parse database. If an object has pending changes, then it is considered to not yet be persisted.
339 340 341 | # File 'lib/parse/model/object.rb', line 339 def persisted? changed? == false && !(@id.nil? || @created_at.nil? || @updated_at.nil? || @acl.nil?) end |
#pretty ⇒ String
Returns a pretty-formatted JSON string.
436 437 438 | # File 'lib/parse/model/object.rb', line 436 def pretty JSON.pretty_generate(as_json) end |
#reload!(opts = {}) ⇒ Object
force reload from the database and replace any local fields with data from the persistent store
347 348 349 350 351 | # File 'lib/parse/model/object.rb', line 347 def reload!(opts = {}) # get the values from the persistence layer fetch!(opts) clear_changes! end |
#rollback! ⇒ Object
This does not reload the object from the persistent store, for this use “reload!” instead.
Locally restores the previous state of the object and clears all dirty tracking information.
407 408 409 | # File 'lib/parse/model/object.rb', line 407 def rollback! restore_attributes end |
#schema ⇒ Hash
Returns the schema structure for this Parse collection from the server.
266 267 268 | # File 'lib/parse/model/object.rb', line 266 def schema self.class.schema end |
#twin ⇒ Parse::Object
This method creates a new object of the same instance type with a copy of all the properties of the current instance. This is useful when you want to create a duplicate record.
426 427 428 429 430 431 432 | # File 'lib/parse/model/object.rb', line 426 def twin h = self.as_json h.delete(Parse::Model::OBJECT_ID) h.delete(:objectId) h.delete(:id) self.class.new h end |
#updates(include_all = false) ⇒ Hash
Returns a hash of all the changes that have been made to the object. By default changes to the Parse::Properties::BASE_KEYS are ignored unless you pass true as an argument.
389 390 391 392 393 394 395 396 397 398 399 400 401 | # File 'lib/parse/model/object.rb', line 389 def updates(include_all = false) h = {} changed.each do |key| next if include_all == false && Parse::Properties::BASE_KEYS.include?(key.to_sym) # lookup the remote Parse field name incase it is different from the local attribute name remote_field = self.field_map[key.to_sym] || key h[remote_field] = send key # make an exception to Parse::Objects, we should return a pointer to them instead h[remote_field] = h[remote_field].parse_pointers if h[remote_field].is_a?(Parse::PointerCollectionProxy) h[remote_field] = h[remote_field].pointer if h[remote_field].respond_to?(:pointer) end h end |
#validate! ⇒ self
Overrides ActiveModel::Validations#validate! instance method. It runs all validations for this object. If validation fails, it raises ActiveModel::ValidationError otherwise it returns the object.
417 418 419 420 | # File 'lib/parse/model/object.rb', line 417 def validate! super self end |