module FmRest::Spyke::Model::Orm
This module adds and extends various ORM features in Spyke
models, including custom query methods, remote script execution and exception-raising persistence methods.
Public Instance Methods
Exception-raising version of `#create`
@param attributes [Hash] the attributes to initialize the
record with
# File lib/fmrest/spyke/model/orm.rb, line 77 def create!(attributes = {}) new(attributes).tap(&:save!) end
Spyke
override – Adds support for Data API script execution.
@option options [String] :script the name of a FileMaker script to execute
upon deletion
# File lib/fmrest/spyke/model/orm.rb, line 179 def destroy(options = {}) # For whatever reason the Data API wants the script params as query # string params for DELETE requests, making this more complicated # than it should be script_query_string = if options.has_key?(:script) "?" + Faraday::Utils.build_query(FmRest::V1.convert_script_params(options[:script])) else "" end self.attributes = delete(uri.to_s + script_query_string) end
Requests execution of a FileMaker script.
@param script_name [String] the name of the FileMaker script to
execute
@param param [String] an optional paramater for the script
# File lib/fmrest/spyke/model/orm.rb, line 87 def execute_script(script_name, param: nil) params = {} params = {"script.param" => param} unless param.nil? request(:get, FmRest::V1::script_path(layout, script_name), params) end
# File lib/fmrest/spyke/model/orm.rb, line 95 def extend_scope_with_fm_params(scope, prefixed: false) prefix = prefixed ? "_" : nil where_options = {} where_options["#{prefix}limit"] = scope.limit_value if scope.limit_value where_options["#{prefix}offset"] = scope.offset_value if scope.offset_value if scope.sort_params.present? where_options["#{prefix}sort"] = prefixed ? scope.sort_params.to_json : scope.sort_params end unless scope.included_portals.nil? where_options["portal"] = prefixed ? scope.included_portals.to_json : scope.included_portals end if scope.portal_params.present? scope.portal_params.each do |portal_param, value| where_options["#{prefix}#{portal_param}"] = value end end if scope.script_params.present? where_options.merge!(scope.script_params) end scope.where(where_options) end
Spyke
override – allows properly setting limit, offset and other options, as well as using the appropriate HTTP method/URL depending on whether there's a query present in the current scope.
@example
Person.query(first_name: "Stefan").fetch # -> POST .../_find
# File lib/fmrest/spyke/model/orm.rb, line 48 def fetch if current_scope.has_query? scope = extend_scope_with_fm_params(current_scope, prefixed: false) scope = scope.where(query: scope.query_params) scope = scope.with(FmRest::V1::find_path(layout)) else scope = extend_scope_with_fm_params(current_scope, prefixed: true) end previous, self.current_scope = current_scope, scope # The DAPI returns a 401 "No records match the request" error when # nothing matches a _find request, so we need to catch it in order # to provide sane behavior (i.e. return an empty resultset) begin current_scope.has_query? ? scoped_request(:post) : super rescue FmRest::APIError::NoMatchingRecordsError => e raise e if raise_on_no_matching_records ::Spyke::Result.new({}) end ensure self.current_scope = previous end
(see destroy
)
@option (see destroy
)
# File lib/fmrest/spyke/model/orm.rb, line 196 def reload(options = {}) scope = self.class scope = scope.script(options[:script]) if options.has_key?(:script) reloaded = scope.find(__record_id) self.attributes = reloaded.attributes self.__mod_id = reloaded.mod_id end
Spyke
override – Adds a number of features to original `#save`:
-
Validations
-
Data API scripts execution
-
Refresh of dirty attributes
@option options [String] :script the name of a FileMaker script to execute
upon saving
@option options [Boolean] :raise_validation_errors whether to raise an
exception if validations fail
@return [true] if saved successfully @return [false] if validations or persistence failed
# File lib/fmrest/spyke/model/orm.rb, line 141 def save(options = {}) callback = persisted? ? :update : :create return false unless perform_save_validations(callback, options) return false unless perform_save_persistence(callback, options) true end
Exception-raising version of `#save`.
@option (see save
)
@return [true] if saved successfully
@raise if validations or presistence failed
# File lib/fmrest/spyke/model/orm.rb, line 158 def save!(options = {}) save(options.merge(raise_validation_errors: true)) end
Exception-raising version of `#update`.
@param new_attributes [Hash] a hash of record attributes to update
the record with
@option (see save
)
# File lib/fmrest/spyke/model/orm.rb, line 169 def update!(new_attributes, options = {}) self.attributes = new_attributes save!(options) end
# File lib/fmrest/spyke/model/orm.rb, line 207 def validate!(context = nil) valid?(context) || raise_validation_error end
Private Instance Methods
# File lib/fmrest/spyke/model/orm.rb, line 240 def build_params_for_save(options) to_params.tap do |params| if options.has_key?(:script) params.merge!(FmRest::V1.convert_script_params(options[:script])) end end end
# File lib/fmrest/spyke/model/orm.rb, line 219 def perform_save_persistence(callback, options) run_callbacks :save do run_callbacks(callback) do begin send self.class.method_for(callback), build_params_for_save(options) rescue APIError::ValidationError => e if options[:raise_validation_errors] raise e else return false end end end end true end
# File lib/fmrest/spyke/model/orm.rb, line 214 def perform_save_validations(context, options) return true if options[:validate] == false options[:raise_validation_errors] ? validate!(context) : validate(context) end
Overwrite ActiveModel's raise_validation_error
to use our own class
# File lib/fmrest/spyke/model/orm.rb, line 250 def raise_validation_error # :doc: raise(ValidationError.new(self)) end