Trophonius
A lightweight, easy to use link between Ruby (on Rails) and FileMaker using the FileMaker Data-API.
Install / Use
/learn @KA-HQ/TrophoniusREADME
Trophonius
A lightweight pure ruby link between Ruby (on Rails) and FileMaker using the FileMaker Data-API.
Do you need support connecting your FileMaker database? Or do you have an awesome ruby project in mind?
Let us know if we can help.
Installation
Install the gem yourself
gem install trophonius
Or add to your gemfile
gem 'trophonius', '~> 2.1'
And run bundle install
Configuration
To begin using the gem create a configuration file in the initializers folder called trophonius.rb. This file should contain all the information the Data-API needs to setup a connection to your database.
To generate this file automatically in a rails app you can use the generator:
rails g trophonius --host location_to.your_filemakerserver.com --database Name_of_your_database
Where --host should contain a url to your FileMaker server and --database should contain the name of your database
Example of the initializer file:
Trophonius.configure do |config|
config.host = "location_to.your_filemakerserver.com"
config.database = "Name_of_your_database"
config.username = "Username to Access the Database" # or Rails.application.credentials.dig(:username) (requires >= Rails 5.2)
config.password = "Y0urAmaz1ngPa$$w0rd" # or Rails.application.credentials.dig(:password) (requires >= Rails 5.2)
config.count_result_script = "script that can be used to count the results (optional)"
config.redis_connection = true # default false, true if you want to store the token in redis
config.ssl = true # or false depending on whether https or http should be used
config.fm_18 = true # use if FileMaker server version >= 18, default true
config.debug = false # will output more information when true
config.pool_size = ENV.fetch('trophonius_pool', 5) # use multiple data api connections with a loadbalancer to improve performance
# USE THE NEXT OPTION WITH CAUTION
config.local_network = true # if true the ssl certificate will not be verified to allow for self-signed certificates
end
Usage
Trophonius is setup to feel like ActiveRecord. You can choose to create a model for every table in your FileMaker app. Just make sure to include the name of the layout the model should look at:
class MyModel < Trophonius::Model
config layout_name: "MyModelsLayout"
end
You can also generate a model automatically using the following command:
rails g trophonius_model --model MyModel --layout MyModelsLayout
Where --model should contain the name you want to give to your model and --layout should contain the name of the layout on which this model should be based on
Or if your layout contains non-modifiable fields:
class MyModel < Trophonius::Model
config layout_name: "MyModelsLayout", non_modifiable_fields: ["PrimaryKey", "RecordID"]
end
Field names
Since FileMaker allows anything to be a field name, Trophonius changes your fieldnames slightly to work like methods for the record. Trophonius changes your field names to a rubystyle, snake_cased name. To retrieve the translations you can use the method MyModel.translations. To use the translations in the create, where and edit methods, Trophonius requires at least one record to exist in order to create the translations. This means that if two of your fields have the same name only one of those fields will be converted to a method, i.e. "New Field" and "New (Field)" will become both "new_field".
Create records
To create a new record in the FileMaker database you only have to call the create method:
MyModel.create(field_one: "Data", number_field: 1)
The new record will be created immediately and filled with the provided data. The fieldnames are the same as the names in FileMaker. If the fieldname in FileMaker contains non-word characters, the fieldname should be in quotes. This method returns the created record as a Trophonius::Record instance. If you have a portal on your layout, you can fill the portal by adding a portal_data parameter:
MyModel.create(field_one: "Data", number_field: 1, portal_data: {
"MyPortalOccurrenceName" => [
{ "portalField" => "value" },
{ "portalField" => "value2" },
{ "portalField" => "value4" }
]
})
The field in your portal_data parameter have to be the same as the fieldnames in FileMaker, currently the translations don't work. You should also add
Get records
Trophonius allows multiple ways to get records. The easiest ways are either .all or .first, which respectively return all records (if you have a foundcount script) or the first 1000000 records or only the first record.
MyModel.all # all records
MyModel.first # first record
If you want a more restricted set of records or a specific record you might want to use the find functionality. To find a single specific record the .find method can be used. This method requires you to provide the recordid you would like to retrieve from FileMaker. When you want to find a set of records where a condition holds, the .where method should be used. This method returns all records where the condition holds, or an empty set if there are no records with this condition.
record = MyModel.find(100) # Record with recordID 100 (if available)
MyModel.where(number_field: 100).to_a # Records where NumberField is 100 (if any)
record.portal.each do |portal_record|
portal_record.child_field
end
If a condition requires multiple statements to be true, you can simply add multiple fields in the same where:
record = MyModel.find(100) # Record with recordID 100 (if available)
MyModel.where(number_field: 100, date_field: Date.today.strftime('%m/%d/%Y')).to_a # Records where NumberField is 100 and date_field contains the date of today(if any)
record.portal.each do |portal_record|
portal_record.child_field
end
Omit records
If you want to find records without the specified query you can use the "not" method. This method will add an omit find request to the query. If the query gets executed, FileMaker will return the records where the condition does not hold.
MyModel.not(number_field: 100).to_a # Records where NumberField is not 100 (if any)
Or find request
MyModel.where(number_field: 100).or(number_field: 101).to_a # Records where NumberField is 100 or 101 (if any)
Sorted find request
MyModel.where(number_field: 100).sort(number_field: 'ascend').to_a # Records where NumberField is 100 sorted by number_field ascending (if any)
Update records
To update the data of a record you can find a record in the FileMaker database and use the assignment operator on it's fields. A field can be accessed in two ways: if the field does not contain any non-word characters it is available as method for the record. Otherwise it is available as a key using the [] operator. Once all fields are set, run the save method to store the new data in FileMaker.
record = MyModel.find(100) # or use MyModel.where and loop over the RecordSet
record.field_one = "New Value"
record.number_field = 42
record["Field With Spaces and Non-word Characters!"] = "New value" # or record.field_with_spaces_and_non_word_characters
record.save
Uploading a file to a container
To upload a file to a container field you can use the upload method on a record. The first parameter, container_name, requires a string containing the name of the container field in filemaker, this process is case sensitive so containerfield ≠ ContainerField. The second parameter is the repetition of the container field (default value is 1). The third parameter, file, is the actual File or Tempfile object you want to upload to your container.
record = MyModel.find(100) # or use MyModel.where and loop over the RecordSet
record.upload(container_name: 'MyContainerField', container_repetition: 1, file: params[:uploaded_file].tempfile)
Delete records
Deleting a record is as simple as finding the record to delete and calling the delete method:
record_to_delete = MyModel.find(100)
record_to_delete.delete
Running a script
To run a FileMaker script from the context of a model you can call the run_script method. This method accepts an optional scriptparameter required by the FileMaker script. The method returns the script result, set by the Exit Script script step in FileMaker.
MyModel.run_script(script: "My Awesome Script", scriptparameter: "ScriptParameter") #the script parameter is optional
Callbacks
A model can have 6 different types of callbacks: before_create, after_create, before_update, after_update, before_delete, after_delete. The callbacks have 2 arguments: a method name or lambda and the arguments to pass to the callback method/lambda. Arguments should be passed as a string.
class MyModel < Trophonius::Model
before_create :run_this_before_created_in_filemaker, [[1, 2, 3], 'second argument']
after_create :run_this_after_created_in_filemaker, [[3, 2, 1]]
before_update :run_this_before_updated_in_filemaker, [[4, 5, 6]]
after_update :run_this_after_updated_in_filemaker, [[6, 5, 4]]
before_destroy :run_this_before_destroyed_in_filemaker, [[7, 8, 9]]
after_destroy :run_this_after_destroyed_in_filemaker, [[9, 8, 7]]
def self.run_this_before_created_in_filemaker(array, string)
puts "#{array.length}, #{string}"
end
def self.run_this_after_created_in_filemaker(array)
puts array
end
def self.run_this_before_updated_in_filemaker(array)
puts array
end
def self.run_this_after_updated_in_filemaker(array)
puts array
end
def self.run_this_before_destroyed_in_filemaker(array)
puts array
end
def self.r
