Class: Trophonius::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/model.rb

Overview

This class will retrieve the records from the FileMaker database and build a RecordSet filled with Record objects. One Record object represents a record in FileMaker.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config:) ⇒ Model

Returns a new instance of Model.



21
22
23
24
25
# File 'lib/model.rb', line 21

def initialize(config:)
  @configuration = config
  @offset = ''
  @limit = ''
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *args, &block) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/model.rb', line 146

def method_missing(method, *args, &block)
  if @current_query.respond_to?(method)
    args << self
    @current_query.send(method, args)
  elsif @current_query.response.respond_to?(method)
    ret_val = @current_query.run_query(method, *args, &block)
    @limit = ''
    @offset = ''
    ret_val
  end
end

Instance Attribute Details

#configurationObject (readonly)

Returns the value of attribute configuration.



18
19
20
# File 'lib/model.rb', line 18

def configuration
  @configuration
end

#current_queryObject

Returns the value of attribute current_query.



19
20
21
# File 'lib/model.rb', line 19

def current_query
  @current_query
end

Class Method Details

.all(sort: {}) ⇒ RecordSet

Retrieve the first 10000000 records from FileMaker from the context of the Model.

Parameters:

  • sort: (Hash) (defaults to: {})

    a hash containing the fields to sort by and the direction to sort in (optional)

Returns:

  • (RecordSet)

    : a RecordSet containing all the Record objects that correspond to the FileMaker records.



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
# File 'lib/model.rb', line 356

def self.all(sort: {})
  create_translations if @configuration.translations.keys.empty?
  path = "/layouts/#{layout_name}/records?"
  path += @limit.present? ? "_limit=#{@limit}" : '_limit=10000000'
  path += "&_offset=#{@offset}" if @offset.present?
  sort = sort.map { |k, v| { fieldName: k, sortOrder: v } }
  path += "&_sort=#{sort.to_json}" unless sort.blank?

  @limit = ''
  @offset = ''
  results = DatabaseRequest.make_request(path, 'get', '{}')
  if results['messages'][0]['code'] == '0'
    r_results = results['response']['data']
    ret_val = RecordSet.new(layout_name, non_modifiable_fields)
    r_results.each do |r|
      hash = build_result(r)
      ret_val << hash
    end
    ret_val.result_count = count
    ret_val
  else
    Error.throw_error(results['messages'][0]['code'])
  end
end

.belongs_to(model_name, primary_key:, foreign_key:) ⇒ Object

Add a belongs to relationship.

Parameters:

  • model_name: (Symbol)

    the name of the model to build a relation with

  • primary_key: (String)

    the name of the field containing the primary to build the relation over

  • foreign_key: (String)

    the name of the field containing the primary to build the relation over



50
51
52
# File 'lib/model.rb', line 50

def self.belongs_to(model_name, primary_key:, foreign_key:)
  @configuration.belongs_to_relations.merge!({ model_name => { primary_key: primary_key, foreign_key: foreign_key } })
end

.belongs_to_relationsHash

Returns the Hash containing the related parent models

Returns:

  • (Hash)

    parent models



97
98
99
# File 'lib/model.rb', line 97

def self.belongs_to_relations
  @configuration.belongs_to_relations
end

.build_result(result) ⇒ Record

Builds the resulting Record

Parameters:

  • result: (JSON)

    the HTTP result from FileMaker

Returns:

  • (Record)

    A Record with singleton_methods for the fields where possible



307
308
309
310
311
# File 'lib/model.rb', line 307

def self.build_result(result)
  record = Trophonius::Record.new(result, name)
  record.layout_name = layout_name
  record
end

.config(configuration) ⇒ Object

Sets up the configuration for the model.

Parameters:

  • configuration: (Hash)

    the hash containing the config to setup the model correctly. configuration = “theFileMakerLayoutForThisModel”, non_modifiable_fields: [“an”, “array”, “containing”, “calculation_fields”, “etc.”]



33
34
35
36
37
38
39
40
41
42
# File 'lib/model.rb', line 33

def self.config(configuration)
  @configuration ||= Configuration.new
  @configuration.layout_name = configuration[:layout_name]
  @configuration.non_modifiable_fields = configuration[:non_modifiable_fields] || []
  @configuration.translations = {}
  @configuration.has_many_relations = {}
  @configuration.belongs_to_relations = {}
  @offset = ''
  @limit = ''
end

.create(field_data, portal_data: {}) ⇒ Record

Creates and saves a record in FileMaker

Parameters:

  • fieldData: (Hash)

    the fields to fill with the data

Returns:

  • (Record)

    the created record Model.create(fieldOne: “Data”)



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/model.rb', line 191

def self.create(field_data, portal_data: {})
  create_translations if @configuration.translations.keys.empty?

  field_data.transform_keys! { |k| (@configuration.translations[k.to_s] || k).to_s }

  portal_data.each do |portal_name, values|
    values.map { |record| record.transform_keys! { |k| "#{portal_name}::#{k}" } }
  end

  body = { fieldData: field_data }
  body.merge!({ portalData: portal_data }) if portal_data.present?

  response = DatabaseRequest.make_request("/layouts/#{layout_name}/records", 'post', body.to_json)

  return throw_field_missing(field_data) if response['messages'][0]['code'] == '102'

  return Error.throw_error(response['messages'][0]['code']) if response['messages'][0]['code'] != '0'

  new_record = DatabaseRequest.make_request("/layouts/#{layout_name}/records/#{response['response']['recordId']}", 'get', '{}')
  record = build_result(new_record['response']['data'][0])
  record.send(:define_singleton_method, 'result_count') { 1 }
  record
end

.create_translationsHash

creates Rails -> FileMaker field translations by requesting the first record

Returns:

  • (Hash)

    translations of the fields Rails -> FileMaker



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/model.rb', line 121

def self.create_translations
  extend Trophonius::Translator
  field_names = if Trophonius.config.fm_18
                  Trophonius::DatabaseRequest.get_layout_field_names(layout_name)
                else
                  DatabaseRequest.retrieve_first(layout_name).dig(
                    'response', 'data', 0, 'fieldData'
                  ).keys
                end
  field_names.each do |field|
    new_name = methodize_field(field.to_s).to_s
    @configuration.translations.merge!(
      { new_name => field.to_s }
    )
  end
  @configuration.translations
end

.delete(record_id) ⇒ Boolean

Deletes a record from FileMaker

Parameters:

  • record_id: (Integer)

    the record id to retrieve from FileMaker

Returns:

  • (Boolean)

    True if the delete was successful



266
267
268
269
270
271
272
273
274
275
276
# File 'lib/model.rb', line 266

def self.delete(record_id)
  create_translations if @configuration.translations.keys.empty?

  url = "layouts/#{layout_name}/records/#{record_id}"
  response = DatabaseRequest.make_request(url, 'delete', '{}')
  if response['messages'][0]['code'] == '0'
    true
  else
    Error.throw_error(response['messages'][0]['code'])
  end
end

.edit(record_id, field_data) ⇒ Boolean

Edits a record in FileMaker

Parameters:

  • record_id: (Integer)

    the record id to edit in FileMaker

  • fieldData: (Hash)

    A hash containing the fields to edit and the new data to fill them with

Returns:

  • (Boolean)

    True if the delete was successful



286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/model.rb', line 286

def self.edit(record_id, field_data)
  url = "layouts/#{layout_name}/records/#{record_id}"
  new_field_data = {}
  create_translations if @configuration.translations.keys.empty?

  field_data.each_key do |k|
    field_name = (@configuration.translations[k.to_s] || k).to_s
    new_field_data.merge!({ field_name => field_data[k] })
  end

  body = "{\"fieldData\": #{new_field_data.to_json}}"
  response = DatabaseRequest.make_request(url, 'patch', body)
  response['messages'][0]['code'] == '0' ? true : Error.throw_error(response['messages'][0]['code'])
end

.find(record_id) ⇒ Record

Finds and returns a Record corresponding to the record_id

Parameters:

  • record_id: (Integer)

    the record id to retrieve from FileMaker

Returns:



246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/model.rb', line 246

def self.find(record_id)
  create_translations if @configuration.translations.keys.empty?

  url = "layouts/#{layout_name}/records/#{record_id}"
  response = DatabaseRequest.make_request(url, 'get', '{}')
  if response['messages'][0]['code'] == '0'
    ret_val = build_result(response['response']['data'][0])
    ret_val.send(:define_singleton_method, 'result_count') { 1 }
    ret_val
  else
    Error.throw_error(response['messages'][0]['code'], record_id)
  end
end

.find_by(field_data) ⇒ Record

Finds and returns the first Record containing fitting the find request

Parameters:

  • fieldData: (Hash)

    the data to find

Returns:

  • (Record)

    a Record object that correspond to FileMaker record fitting the find request Model.find_by(fieldOne: “Data”)



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/model.rb', line 222

def self.find_by(field_data)
  url = "layouts/#{layout_name}/_find?_limit=1"
  create_translations if @configuration.translations.keys.empty?

  field_data.transform_keys! { |k| (@configuration.translations[k.to_s] || k).to_s }

  body = { query: [field_data], limit: '1' }.to_json
  response = DatabaseRequest.make_request(url, 'post', body)
  code = response['messages'][0]['code']

  return nil if %w[101 401].include?(code)

  Error.throw_error(code) if code != '0'

  r_results = response['response']['data']
  build_result(r_results.first) if r_results.first.present?
end

.firstRecord

Retrieve the first record from FileMaker from the context of the Model.

Returns:

  • (Record)

    : a Record corresponding to the FileMaker record.



317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/model.rb', line 317

def self.first
  create_translations if @configuration.translations.keys.empty?
  results = DatabaseRequest.retrieve_first(layout_name)
  if results['messages'][0]['code'] == '0'
    r_results = results['response']['data']
    ret_val = r_results.empty? ? Trophonius::Record.new({}, name) : build_result(r_results[0])
    ret_val.send(:define_singleton_method, 'result_count') { r_results.empty? ? 0 : 1 }
    ret_val
  else
    Error.throw_error(results['messages'][0]['code'])
  end
end

.has_many(model_name, primary_key:, foreign_key:) ⇒ Object

Add a has many relationship.

Parameters:

  • model_name: (Symbol)

    the name of the model to build a relation with

  • primary_key: (String)

    the name of the field containing the primary to build the relation over

  • foreign_key: (String)

    the name of the field containing the primary to build the relation over



60
61
62
# File 'lib/model.rb', line 60

def self.has_many(model_name, primary_key:, foreign_key:)
  @configuration.has_many_relations.merge!({ model_name => { primary_key: primary_key, foreign_key: foreign_key } })
end

.has_many_relationsHash

Returns the Hash containing the related parent models

Returns:

  • (Hash)

    child models



89
90
91
# File 'lib/model.rb', line 89

def self.has_many_relations
  @configuration.has_many_relations
end

.layout_nameString

Returns the FileMaker layout this Model corresponds to

Returns:

  • (String)

    layout name of the model



81
82
83
# File 'lib/model.rb', line 81

def self.layout_name
  @configuration.layout_name
end

.method_missing(method, *args) ⇒ Object



139
140
141
142
143
144
# File 'lib/model.rb', line 139

def self.method_missing(method, *args)
  new_instance = Trophonius::Model.new(config: @configuration)
  new_instance.current_query = Trophonius::Query.new(trophonius_model: self, limit: @limit, offset: @offset)
  args << new_instance
  new_instance.current_query.send(method, args) if new_instance.current_query.respond_to?(method)
end

.non_modifiable_fields[Array]

Returns the fields that FileMaker won’t allow us to modify

Returns:

  • ([Array])

    fields that FileMaker won’t allow us to modify



105
106
107
# File 'lib/model.rb', line 105

def self.non_modifiable_fields
  @configuration.non_modifiable_fields
end

.paginate(page, limit) ⇒ Trophonius::Model

Limits the found record set.

Parameters:

  • page: (Integer)

    number of current page

  • limit: (Integer)

    number of records retreived

Returns:



71
72
73
74
75
# File 'lib/model.rb', line 71

def self.paginate(page, limit)
  @offset = (((page * limit) - limit) + 1).to_s
  @limit = limit.to_s
  self
end

.run_script(script: '', scriptparameter: '') ⇒ String

Runs a FileMaker script from the context of the Model.

Parameters:

  • script: (String) (defaults to: '')

    the FileMaker script to run

  • scriptparameter: (String) (defaults to: '')

    the parameter required by the FileMaker script

Returns:

  • (String)

    : string representing the script result returned by FileMaker



338
339
340
341
342
343
344
345
346
347
348
# File 'lib/model.rb', line 338

def self.run_script(script: '', scriptparameter: '')
  create_translations if @configuration.translations.keys.empty?
  result = DatabaseRequest.run_script(script, scriptparameter, layout_name)
  if result['messages'][0]['code'] != '0'
    Error.throw_error(result['messages'][0]['code'])
  elsif result['response']['scriptResult'] == '403'
    Error.throw_error(403)
  else
    result['response']['scriptResult']
  end
end

.translationsHash

Returns the translations of the fields

Returns:

  • (Hash)

    translations of the fields Rails -> FileMaker



113
114
115
# File 'lib/model.rb', line 113

def self.translations
  @configuration.translations
end

.where(field_data) ⇒ Trophonius::Model

Finds all records in FileMaker corresponding to the requested query

Parameters:

  • fieldData: (Hash)

    the data to find

Returns:



163
164
165
166
167
168
169
170
# File 'lib/model.rb', line 163

def self.where(field_data)
  create_translations if @configuration.translations.keys.empty?

  new_instance = Trophonius::Model.new(config: @configuration)
  new_instance.current_query = Trophonius::Query.new(trophonius_model: self, limit: @limit, offset: @offset)
  new_instance.current_query.build_query[0].merge!(field_data)
  new_instance
end

Instance Method Details

#where(field_data) ⇒ Trophonius::Model

Finds all records in FileMaker corresponding to the requested query This method is created to enable where chaining

Parameters:

  • fieldData: (Hash)

    the data to find

Returns:



179
180
181
182
# File 'lib/model.rb', line 179

def where(field_data)
  @current_query.build_query[0].merge!(field_data)
  self
end