Module: ModelAttribute::InstanceMethods
- Defined in:
- lib/model_attribute.rb
Instance Method Summary collapse
- #==(other) ⇒ Object (also: #eql?)
- #attributes ⇒ Object
-
#attributes_for_json ⇒ Object
Attributes suitable for serializing to a JSON string.
- #cast(value, type) ⇒ Object
- #changes ⇒ Object
-
#changes_for_json ⇒ Object
Changed attributes suitable for serializing to a JSON string.
-
#inspect ⇒ Object
Includes the class name and all the attributes and their values.
- #read_attribute(name) ⇒ Object
- #set_attributes(attributes, can_set_private_attrs = false) ⇒ Object
- #write_attribute(name, value, type = nil) ⇒ Object
Instance Method Details
#==(other) ⇒ Object Also known as: eql?
98 99 100 101 102 103 104 105 |
# File 'lib/model_attribute.rb', line 98 def ==(other) return true if equal?(other) if respond_to?(:id) other.kind_of?(self.class) && id == other.id else other.kind_of?(self.class) && attributes == other.attributes end end |
#attributes ⇒ Object
86 87 88 89 90 |
# File 'lib/model_attribute.rb', line 86 def attributes self.class.attributes.each_with_object({}) do |name, attributes| attributes[name] = read_attribute(name) end end |
#attributes_for_json ⇒ Object
Attributes suitable for serializing to a JSON string.
- Attribute keys are strings (for 'strict' JSON dumping).
- Attributes with a nil value are omitted to speed serialization.
- :time attributes are serialized as an Integer giving the number of
milliseconds since the epoch.
118 119 120 121 122 123 124 125 126 |
# File 'lib/model_attribute.rb', line 118 def attributes_for_json self.class.attributes.each_with_object({}) do |name, attributes| value = read_attribute(name) unless value.nil? value = (value.to_f * 1000).to_i if value.is_a? Time attributes[name.to_s] = value end end end |
#cast(value, type) ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/model_attribute.rb', line 155 def cast(value, type) return nil if value.nil? case type when :integer int = Integer(value) float = Float(value) raise "Can't cast #{value.inspect} to an integer without loss of precision" unless int == float int when :boolean if !!value == value value elsif value == 't' true elsif value == 'f' false else raise "Can't cast #{value.inspect} to boolean" end when :time case value when Time value when Date, DateTime value.to_time when Integer # Assume milliseconds since epoch. Time.at(value / 1000.0) when Numeric # Numeric, but not an integer. Assume seconds since epoch. Time.at(value) else Time.parse(value) end when :string String(value) when :json if Json.valid?(value) value else raise "JSON only supports nil, numeric, string, boolean and arrays and hashes of those." end else raise UnsupportedTypeError.new(type) end end |
#changes ⇒ Object
108 109 110 |
# File 'lib/model_attribute.rb', line 108 def changes @changes ||= {} #HashWithIndifferentAccess.new end |
#changes_for_json ⇒ Object
Changed attributes suitable for serializing to a JSON string. Returns a hash from attribute name (as a string) to the new value of that attribute, for attributes that have changed.
- :time attributes are serialized as an Integer giving the number of
milliseconds since the epoch.
- Unlike attributes_for_json, attributes that have changed to a nil value
*are* included.
136 137 138 139 140 141 142 143 144 |
# File 'lib/model_attribute.rb', line 136 def changes_for_json hash = {} changes.each do |attr_name, (_old_value, new_value)| new_value = (new_value.to_f * 1000).to_i if new_value.is_a? Time hash[attr_name.to_s] = new_value end hash end |
#inspect ⇒ Object
Includes the class name and all the attributes and their values. e.g. “#<User id: 1, paid: true, name: "Fred", created_at: 2014-12-25 08:00:00 +0000>”
148 149 150 151 152 153 |
# File 'lib/model_attribute.rb', line 148 def inspect attribute_string = self.class.attributes.map do |key| "#{key}: #{read_attribute(key).inspect}" end.join(', ') "#<#{self.class} #{attribute_string}>" end |
#read_attribute(name) ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/model_attribute.rb', line 77 def read_attribute(name) ivar_name = "@#{name}" if instance_variable_defined?(ivar_name) instance_variable_get(ivar_name) elsif !self.class.attributes.include?(name.to_sym) raise InvalidAttributeNameError.new(name) end end |
#set_attributes(attributes, can_set_private_attrs = false) ⇒ Object
92 93 94 95 96 |
# File 'lib/model_attribute.rb', line 92 def set_attributes(attributes, can_set_private_attrs = false) attributes.each do |key, value| send("#{key}=", value) if respond_to?("#{key}=", can_set_private_attrs) end end |
#write_attribute(name, value, type = nil) ⇒ Object
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 |
# File 'lib/model_attribute.rb', line 51 def write_attribute(name, value, type = nil) name = name.to_sym # Don't want to expose attribute types as a method on the class, so access # via a back door. type ||= self.class.instance_variable_get('@attribute_types')[name] raise InvalidAttributeNameError.new(name) unless type value = cast(value, type) return if value == read_attribute(name) if changes.has_key? name original = changes[name].first else original = read_attribute(name) end if original == value changes.delete(name) else changes[name] = [original, value] end instance_variable_set("@#{name}", value) end |