Module: Neo4j::Rails::Attributes

Extended by:
ActiveSupport::Concern, TxMethods
Included in:
Model, Relationship
Defined in:
lib/neo4j/rails/attributes.rb

Overview

This module handles the getting, setting and updating of attributes or properties in a Railsy way. This typically means not writing anything to the DB until the object is saved (after validation).

Externally, when we talk about properties (e.g. #property?, #property_names), we mean all of the stored properties for this object include the 'hidden' props with underscores at the beginning such as _neo_id and _classname. When we talk about attributes, we mean all the properties apart from those hidden ones.

This mixin defines a number of class methods, see #ClassMethods.

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary (collapse)

Methods included from TxMethods

tx_methods

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

- (Object) method_missing(method_id, *args, &block) (protected)

THIS IS ONLY NEEDED IN ACTIVEMODEL < 3.2 To get ActiveModel::Dirty to work, we need to be able to call undeclared properties as though they have get methods



408
409
410
411
412
413
414
415
# File 'lib/neo4j/rails/attributes.rb', line 408

def method_missing(method_id, *args, &block)
  method_name = method_id.to_s
  if property?(method_name)
    self[method_name]
  else
    super
  end
end

Instance Method Details

- (Object) _classname



372
373
374
# File 'lib/neo4j/rails/attributes.rb', line 372

def _classname
  self.class.to_s
end

- (Boolean) attribute?(name)

Return true if method_name is the name of an appropriate attribute method

Returns:

  • (Boolean)


197
198
199
# File 'lib/neo4j/rails/attributes.rb', line 197

def attribute?(name)
  name[0] != ?_ && property?(name)
end

- (Object) attribute_defaults



87
88
89
# File 'lib/neo4j/rails/attributes.rb', line 87

def attribute_defaults
  self.class.attribute_defaults || {}
end

- (Object) attribute_names

Known attributes are either in the @_properties, the declared attributes or the property keys for the persisted node. Any attributes that start with _ are rejected



177
178
179
# File 'lib/neo4j/rails/attributes.rb', line 177

def attribute_names
  property_names.reject { |property_name| _invalid_attribute_name?(property_name) }
end

- (Object) attributes

Return all the attributes for this model as a hash attr => value. Doesn't include properties that start with _.



155
156
157
158
159
160
161
# File 'lib/neo4j/rails/attributes.rb', line 155

def attributes
  ret = {}
  attribute_names.each do |attribute_name|
    ret[attribute_name] = self.class._decl_props[attribute_name.to_sym] ? send(attribute_name) : send(:[], attribute_name)
  end
  ret
end

- (Object) attributes=(attributes, guard_protected_attributes = true)

Mass-assign attributes. Stops any protected attributes from being assigned.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/neo4j/rails/attributes.rb', line 72

def attributes=(attributes, guard_protected_attributes = true)
  attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes

  multi_parameter_attributes = []
  attributes.each do |k, v|
    if k.to_s.include?("(")
      multi_parameter_attributes << [k, v]
    else
      respond_to?("#{k}=") ? send("#{k}=", v) : self[k] = v
    end
  end

  assign_multiparameter_attributes(multi_parameter_attributes)
end

- (Object) hash



125
126
127
# File 'lib/neo4j/rails/attributes.rb', line 125

def hash
  persisted? ? _java_entity.neo_id.hash : super
end

- (Boolean) property?(name)

Known properties are either in the @_properties, the declared properties or the property keys for the persisted node

Returns:

  • (Boolean)


183
184
185
186
187
188
# File 'lib/neo4j/rails/attributes.rb', line 183

def property?(name)
  return false unless @_properties
  @_properties.has_key?(name) ||
      self.class._decl_props.has_key?(name) ||
      persisted? && super
end

- (Boolean) property_changed?

Returns:

  • (Boolean)


190
191
192
193
# File 'lib/neo4j/rails/attributes.rb', line 190

def property_changed?
  return !@_properties.empty? unless persisted?
  !!@_properties.keys.find { |k| self._java_entity[k] != @_properties[k] }
end

- (Object) property_names

Known properties are either in the @_properties, the declared attributes or the property keys for the persisted node.



165
166
167
168
169
170
171
172
# File 'lib/neo4j/rails/attributes.rb', line 165

def property_names
  # initialize @_properties if needed since
  # we can ask property names before the object is initialized (active_support initialize callbacks, respond_to?)
  @_properties ||= {}
  keys = @_properties.keys + self.class._decl_props.keys.map(&:to_s)
  keys += _java_entity.property_keys.to_a if persisted?
  keys.flatten.uniq
end

- (Object) props

Return the properties from the Neo4j Node, merged with those that haven't yet been saved



145
146
147
148
149
150
151
# File 'lib/neo4j/rails/attributes.rb', line 145

def props
  ret = {}
  property_names.each do |property_name|
    ret[property_name] = respond_to?(property_name) ? send(property_name) : send(:[], property_name)
  end
  ret
end

- (Object) read_attribute(key)

Returns the locally stored value for the key or retrieves the value from the DB if we don't have one



229
230
231
232
233
234
235
236
# File 'lib/neo4j/rails/attributes.rb', line 229

def read_attribute(key)
  key = key.to_s
  if @_properties.has_key?(key)
    @_properties[key]
  else
    @_properties[key] = (!new_record? && _java_entity.has_property?(key)) ? read_property_from_db(key) : attribute_defaults[key]
  end
end

- (Object) read_attribute_with_type_conversion(property)

Wrap the getter in a conversion from Java to Ruby



203
204
205
# File 'lib/neo4j/rails/attributes.rb', line 203

def read_attribute_with_type_conversion(property)
  self.class._converter(property).to_ruby(read_attribute_without_type_conversion(property))
end

- (Object) to_key

Returns an Enumerable of all (primary) key attributes or nil if model.persisted? is false



139
140
141
# File 'lib/neo4j/rails/attributes.rb', line 139

def to_key
  persisted? ? [id] : nil
end

- (Object) to_model



133
134
135
# File 'lib/neo4j/rails/attributes.rb', line 133

def to_model
  self
end

- (Object) to_param



129
130
131
# File 'lib/neo4j/rails/attributes.rb', line 129

def to_param
  persisted? ? neo_id.to_s : nil
end

- (Object) update_attribute(name, value)

Updates a single attribute and saves the record. This is especially useful for boolean flags on existing records. Also note that

  • Validation is skipped.

  • Callbacks are invoked.

  • Updates all the attributes that are dirty in this object.



120
121
122
123
# File 'lib/neo4j/rails/attributes.rb', line 120

def update_attribute(name, value)
  respond_to?("#{name}=") ? send("#{name}=", value) : self[name] = value
  save(:validate => false)
end

- (Object) update_attributes(attributes)

Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved. If saving fails because the resource is invalid then false will be returned.



93
94
95
96
# File 'lib/neo4j/rails/attributes.rb', line 93

def update_attributes(attributes)
  self.attributes = attributes
  save
end

- (Object) update_attributes!(attributes)

Same as #update_attributes, but raises an exception if saving fails.



100
101
102
103
# File 'lib/neo4j/rails/attributes.rb', line 100

def update_attributes!(attributes)
  self.attributes = attributes
  save!
end

- (Object) write_attribute(key, value)

The behaviour of []= changes with a Rails Model, where nothing gets written to Neo4j until the object is saved, during which time all the validations and callbacks are run to ensure correctness



218
219
220
221
222
223
224
225
# File 'lib/neo4j/rails/attributes.rb', line 218

def write_attribute(key, value)
  key_s = key.to_s
  if !@_properties.has_key?(key_s) || @_properties[key_s] != value
    attribute_will_change!(key_s)
    @_properties[key_s] = value.nil? ? attribute_defaults[key_s] : value
  end
  value
end

- (Object) write_attribute_with_type_conversion(property, value)

Wrap the setter in a conversion from Ruby to Java



208
209
210
211
212
# File 'lib/neo4j/rails/attributes.rb', line 208

def write_attribute_with_type_conversion(property, value)
  @_properties_before_type_cast[property.to_sym]=value if self.class._decl_props.has_key? property.to_sym
  conv_value = self.class._converter(property.to_sym).to_java(value)
  write_attribute_without_type_conversion(property, conv_value)
end