module FmRest::Spyke::Model::Attributes
Extends Spyke
models with support for mapped attributes, `ActiveModel::Dirty` and forbidden attributes (e.g. Rails' `params.permit`).
Public Instance Methods
_fmrest_attribute_methods_container()
click to toggle source
# File lib/fmrest/spyke/model/attributes.rb, line 92 def _fmrest_attribute_methods_container @fmrest_attribute_methods_container ||= Module.new.tap { |mod| include mod } end
_fmrest_define_attribute(from, to)
click to toggle source
# File lib/fmrest/spyke/model/attributes.rb, line 96 def _fmrest_define_attribute(from, to) # We use a setter here instead of injecting the hash key/value pair # directly with #[]= so that we don't change the mapped_attributes # hash on the parent class. The resulting hash is frozen for the # same reason. self.mapped_attributes = mapped_attributes.merge(from => to).freeze _fmrest_attribute_methods_container.module_eval do define_method(from) do attribute(to) end define_method(:"#{from}=") do |value| send("#{from}_will_change!") unless value == send(from) set_attribute(to, value) end end # Define ActiveModel::Dirty's methods define_attribute_method(from) end
attributes(*attrs)
click to toggle source
Spyke
override
Similar to Spyke::Base.attributes, but allows defining attribute methods that map to FM attributes with different names.
@example
class Person < Spyke::Base include FmRest::Spyke::Model attributes first_name: "FstName", last_name: "LstName" end p = Person.new p.first_name = "Jojo" p.attributes # => { "FstName" => "Jojo" }
# File lib/fmrest/spyke/model/attributes.rb, line 59 def attributes(*attrs) if attrs.length == 1 && attrs.first.kind_of?(Hash) attrs.first.each { |from, to| _fmrest_define_attribute(from, to) } else attrs.each { |attr| _fmrest_define_attribute(attr, attr) } end end
attributes=(new_attributes)
click to toggle source
Spyke
override – Adds support for forbidden attributes (i.e. Rails' `params.permit`, etc.)
# File lib/fmrest/spyke/model/attributes.rb, line 128 def attributes=(new_attributes) @spyke_attributes ||= ::Spyke::Attributes.new(scope.params) return unless new_attributes && !new_attributes.empty? use_setters(sanitize_for_mass_assignment(new_attributes)) end
new_or_return(attributes_or_object, *_)
click to toggle source
Spyke
override (private)
Called whenever loading records from the HTTP API, so we can reset dirty info on freshly loaded records
See: github.com/balvig/spyke/blob/master/lib/spyke/http.rb
Calls superclass method
# File lib/fmrest/spyke/model/attributes.rb, line 76 def new_or_return(attributes_or_object, *_) # In case of an existing Spyke object return it as is so that we # don't accidentally remove dirty data from associations return super if attributes_or_object.is_a?(::Spyke::Base) super.tap do |record| # In ActiveModel 4.x #clear_changes_information is a private # method, so we need to call it with send() in that case, but # keep calling it normally for AM5+ if record.respond_to?(:clear_changes_information) record.clear_changes_information else record.send(:clear_changes_information) end end end
reload(*args)
click to toggle source
Spyke
override – Adds AM::Dirty support
Calls superclass method
# File lib/fmrest/spyke/model/attributes.rb, line 121 def reload(*args) super.tap { |r| clear_changes_information } end
Private Instance Methods
changed_params()
click to toggle source
# File lib/fmrest/spyke/model/attributes.rb, line 136 def changed_params attributes.to_params.slice(*mapped_changed) end
changes_applied_after_save()
click to toggle source
# File lib/fmrest/spyke/model/attributes.rb, line 152 def changes_applied_after_save changes_applied portals.each(&:parent_changes_applied) end
inspect_attributes()
click to toggle source
Spyke
override (private) – Use known mapped_attributes for inspect
# File lib/fmrest/spyke/model/attributes.rb, line 146 def inspect_attributes mapped_attributes.except(primary_key).map do |k, v| "#{k}: #{attribute(v).inspect}" end.join(', ') end
mapped_changed()
click to toggle source
# File lib/fmrest/spyke/model/attributes.rb, line 140 def mapped_changed mapped_attributes.values_at(*changed) end