fmrest-rails 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8252ef182909d4dc2175c7d33ab64a3450054d093a95d8021966eb9841e4cbb6
4
+ data.tar.gz: bd810bccbdc3f4fbaba17f325158ae25294ebd4bb48f41699bf05e86f0a1fdaa
5
+ SHA512:
6
+ metadata.gz: e915feb3a290fc7e3a9464f7b94fa67d3cb58617152684a6209a138fcfc1dd4eb6e7c45a996232b35c14ed360887dfdad814e28ddde428afacf50838f7d85a88
7
+ data.tar.gz: 420fe28f935ee3a1f970ccb9127c2f506471d3b088d304dec40868a2feeb49386db48c1c6a963cf5f4197cfe05c984de86f8961f58f3efb19b77d5f48b7ce3e0
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --markup markdown
2
+ --plugin activesupport-concern
3
+ lib/**/*.rb
4
+ -
5
+ docs/*
data/CHANGELOG.md ADDED
@@ -0,0 +1,188 @@
1
+ ## Changelog
2
+
3
+ ### 0.21.0
4
+
5
+ * Support for Spyke 7 and Faraday 2
6
+ * Drop support for Faraday 1
7
+ * Drop support for Ruby 2.5
8
+
9
+ ### 0.20.0
10
+
11
+ * Forward proxy options to AWS Client when using `fmrest-cloud` gem
12
+
13
+ ### 0.19.0
14
+
15
+ * Added native support for FileMaker Cloud through the `fmrest-cloud` gem
16
+
17
+ ### 0.18.0
18
+
19
+ * Better support for portals with mismatching field qualifiers
20
+ * Better ergonomics for script execution, improved documentation
21
+ * Defining an attribute on a model that would collide with an existing method
22
+ now raises an error
23
+ * Cleared Faraday deprecation messages on authentication methods
24
+ * Handle FileMaker Cloud case where HTTP 401 Unauthorized with content-type
25
+ text/html is returned after token expiry
26
+ * Add retry option to Rescuable mixin
27
+ * Added fmrest-ruby/VERSION to User-Agent headers
28
+
29
+ ### 0.17.1
30
+
31
+ * Fixed crash when `fmid_token` is set but `username` isn't
32
+
33
+ ### 0.17.0
34
+
35
+ * Added support for Claris ID token login
36
+ * Added ability to use procs in settings
37
+ * Added `Rescuable` mixin
38
+
39
+ ### 0.16.0
40
+
41
+ * Added `FmRest.logger=`
42
+ * Handle serialization of `nil`, `true` and `false` values
43
+
44
+ ### 0.15.2
45
+
46
+ * Fixed autoloading of `FmRest::Layout`
47
+
48
+ ### 0.15.0
49
+
50
+ * Much improved querying API (see documentation on querying), adding new
51
+ `.query` capabilities, as well as two new methods: `.match` and `.or`
52
+
53
+ ### 0.14.0
54
+
55
+ * Aliased `FmRest::Spyke::Base` as `FmRest::Layout` (now preferred), and
56
+ provided a shortcut version for setting the layout name (e.g. `class Foo <
57
+ FmRest::Layout("LayoutName")`)
58
+ * Made `layout` class setting subclass-inheritable
59
+
60
+ ### 0.13.1
61
+
62
+ * Fixed downloading of container field data from FMS19+
63
+
64
+ ### 0.13.0
65
+
66
+ * Split `fmrest` gem into `fmrest-core` and `fmrest-spyke`. `fmrest` becomes a
67
+ wrapper for the two new gems.
68
+ * Fixed bug preventing connection databases with spaces in their names.
69
+ * Improved portal support with ability to delete portal records, and better
70
+ refreshing of portal records after saving the parent.
71
+ * `FmRest::Spyke::Base#__record_id` and `FmRest::Spyke::Base#__mod_id` now
72
+ always return integers if set.
73
+
74
+ ### 0.12.0
75
+
76
+ * Rename `FmRest::Spyke::Base#id=` to `FmRest::Spyke::Base#__record_id=` to
77
+ prevent clobbering of FileMaker layout-defined fields
78
+ * Removed previously deprecated `FmRest::Spyke::Base(config)` syntax
79
+ * Better yard documentation
80
+
81
+ ### 0.11.1
82
+
83
+ * Fixed a couple crashes due to missing constants
84
+
85
+ ### 0.11.0
86
+
87
+ * Added custom class for connection settings, providing indifferent access
88
+ (i.e. keys can be strings or symbols), and centralized default values and
89
+ validations
90
+ * Added `:autologin`, `:token` and `:token_store` connection settings
91
+ * Added `FmRest::Base.fmrest_config_overlay=` and related methods
92
+ * Added `FmRest::V1.request_auth_token` and
93
+ `FmRest::Spyke::Base.request_auth_token` (as well as `!`-suffixed versions
94
+ which raise exceptions on failure)
95
+
96
+ ### 0.10.1
97
+
98
+ * Fixed `URI.escape` obsolete warning messages in Ruby 2.7 by replacing it with
99
+ `URI.encode_www_form_component`
100
+ ([PR#40](https://github.com/beezwax/fmrest-ruby/pull/40))
101
+
102
+ ### 0.10.0
103
+
104
+ * Added `FmRest::StringDateAwareness` module to correct some issues when using
105
+ `FmRest::StringDate`
106
+ * Added basic timezones support
107
+ * Deprecated `class < FmRest::Spyke::Base(config_hash)` syntax in favor of
108
+ using `self.fmrest_config=`
109
+
110
+ ### 0.9.0
111
+
112
+ * Added `FmRest::Spyke::Base.set_globals`
113
+
114
+ ### 0.8.0
115
+
116
+ * Improved metadata when using `FmRest::Spyke::Model`. Metadata now uses
117
+ Struct/OpenStruct, so properties are accessible through `.property`, as well
118
+ as `[:property]`
119
+ * Added batch-finders `.find_in_batches` and `.find_each` for
120
+ * `FmRest::Spyke::Base`
121
+
122
+ ### 0.7.1
123
+
124
+ * Made sure `Model.find_one` and `Model.find_some` work without needing to call
125
+ `Model.all` in between
126
+
127
+ ### 0.7.0
128
+
129
+ * Added date coercion feature
130
+
131
+ ### 0.6.0
132
+
133
+ * Implemented session logout
134
+ ([#16](https://github.com/beezwax/fmrest-ruby/issues/16))
135
+
136
+ ### 0.5.2
137
+
138
+ * Improved support for legacy ActiveModel 4.x
139
+
140
+ ### 0.5.1
141
+
142
+ * Alias `:username` option as `:account_name` for ginjo-rfm gem
143
+ cross-compatibility
144
+
145
+ ### 0.5.0
146
+
147
+ * Much improved script execution support
148
+ ([#20](https://github.com/beezwax/fmrest-ruby/issues/20))
149
+ * Fixed bug when setting `default_limi` and trying to find a record
150
+ ([35](https://github.com/beezwax/fmrest-ruby/issues/35))
151
+
152
+ ### 0.4.1
153
+
154
+ * Prevent raising an exception when a /\_find request yields no results
155
+ ([#33](https://github.com/beezwax/fmrest-ruby/issues/33) and
156
+ [#34](https://github.com/beezwax/fmrest-ruby/issues/34))
157
+
158
+ ### 0.4.0
159
+
160
+ * Implement ability to set limit and offset for portals
161
+ * Implement disabling and requesting all portals
162
+
163
+ ### 0.3.3
164
+
165
+ * Fix encoding of paths for layouts with brackets in them (e.g. `"\[Very Ugly\]
166
+ Layout"`)
167
+ * Raise an error if `"id"` is assigned as an attribute on a model, as it's
168
+ currently a reserved method name by Spyke
169
+
170
+ ### 0.3.2
171
+
172
+ * Fixed support for ActiveSupport < 5.2
173
+ ([#27](https://github.com/beezwax/fmrest-ruby/issues/27))
174
+
175
+ ### 0.3.0
176
+
177
+ * Added Moneta token store
178
+
179
+ ### 0.2.5
180
+
181
+ * Fixed crash in `fetch_container_data` when no proxy options were set
182
+
183
+ ### 0.2.4
184
+
185
+ * Use `String#=~` instead of `String#match?` for Ruby <2.4 compatibility (Fixes
186
+ [#26](https://github.com/beezwax/fmrest-ruby/issues/26))
187
+ * Deprecated `FmRest.config` in favor of `FmRest.default_connection_settings`
188
+ * Honor Faraday SSL and proxy settings when fetching container files
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2018 Pedro Carbajal and Beezwax Datatools, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,579 @@
1
+ # fmrest-ruby
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/fmrest.svg?style=flat)](https://rubygems.org/gems/fmrest)
4
+ ![CI](https://github.com/beezwax/fmrest-ruby/workflows/CI/badge.svg)
5
+ [![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://rubydoc.info/github/beezwax/fmrest-ruby)
6
+ [![Powered by Beezwax](https://img.shields.io/badge/Powered%20By-Beezwax-gold?logo=data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMTA5IiBoZWlnaHQ9IjEwOSIgdmlld0JveD0iMCAwIDEwOSAxMDkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQogICA8Zz4NCiAgICAgIDxwYXRoIGQ9Ik01MC44IDEwNi42MjVDNTkuMSA5OS4zMjUgNjEuOSA5MS42MjUgNjEuOSA5MS42MjVDNjMuMiA4Ny43MjUgNjQuNyA4NC41MjUgNjQuNyA2OS4zMjVDNjQuNyA0Ni40MjUgNTYuMiAzOC45MjUgNDcgMzIuMDI1QzQwLjggMjcuMzI1IDI0LjkgMjEuMTI1IDE1LjUgMTcuNjI1TDIuMjk5OTggMjUuMTI1QzEuNDk5OTggMjUuNzI1IDAuOTk5OTc2IDI2LjIyNSAwLjU5OTk3NiAyNi44MjVDMjQuNCAzMi4xMjUgNDEuNSA0OC4wMjUgNDEuNSA2Ni44MjVDNDEuNSA3OC4yMjUgMzUuMSA4OC42MjUgMjQuOSA5Ni4xMjVMNDQuNyAxMDcuNTI1QzQ1LjEgMTA3LjcyNSA0NiAxMDguMTI1IDQ3LjMgMTA4LjEyNUM0Ny45IDEwOC4xMjUgNDkgMTA3LjkyNSA1MC4zIDEwNi44MjVMNTAuOCAxMDYuNjI1WiIgZmlsbD0iI0ZGRDkzOSI+PC9wYXRoPg0KICAgICAgPHBhdGggZD0iTTIyLjkgMTMuMzI0OEw0NCAyMC40MjQ4QzY0LjYgMjcuNzI0OCA3My4yIDM3LjgyNDggNzMuMiAzNy44MjQ4Qzg0LjUgNDkuMTI0OCA4My4yIDYxLjYyNDggODMuMiA3Ni44MjQ4QzgzLjIgODAuNjI0OCA4Mi42IDg0LjkyNDggODEuNyA4OS4wMjQ4TDkzIDgyLjYyNDhDOTUuNiA4MS4xMjQ4IDk1LjYgNzcuOTI0OCA5NS42IDc3LjkyNDhWMjkuMzI0OEM5NS42IDI2LjEyNDggOTMgMjQuNjI0OCA5MyAyNC42MjQ4TDcyLjUgMTMuMjI0OEw1MC42IDAuNjI0ODQ1QzQ4LjEgLTAuNjc1MTU1IDQ1LjUgMC40MjQ4NDUgNDUuMyAwLjYyNDg0NUwyMy4xIDEzLjMyNDhIMjIuOVoiIGZpbGw9IiNGRkQ5MzkiPjwvcGF0aD4NCiAgICAgIDxwYXRoIGQ9Ik0wLjEgMzEuNTI0NFY3OC4yMjQ0QzAuMSA4MC44MjQ0IDIuMiA4Mi4zMjQ0IDIuNyA4Mi43MjQ0TDE0LjggODkuNjI0NEwxNy44IDkxLjMyNDRDMjQuNCA4NC43MjQ0IDI4LjQgNzYuMzI0NCAyOC41IDY3LjEyNDRDMjguNSA1MS41MjQ0IDE2LjggMzguMDI0NCAwIDMxLjUyNDRIMC4xWiIgZmlsbD0iI0ZGRDkzOSI+PC9wYXRoPg0KICAgPC9nPg0KPC9zdmc+)](https://beezwax.net/)
7
+
8
+ A Ruby client for
9
+ [FileMaker's Data API](https://help.claris.com/en/data-api-guide)
10
+ with ActiveRecord-ish ORM features.
11
+
12
+ While pretty feature-rich, fmrest-ruby doesn't yet support 100% of FileMaker
13
+ 19's Data API features. See the [implementation completeness
14
+ table](#api-implementation-completeness-table) to check if a feature you need
15
+ is natively supported by the gem.
16
+
17
+ Need Ruby or FileMaker consulting? Contact us at
18
+ [Beezwax.net](https://beezwax.net/)
19
+
20
+ ## Gems
21
+
22
+ The `fmrest` gem is a wrapper for these gems:
23
+
24
+ * `fmrest-spyke`, providing an ActiveRecord-like ORM library built on top
25
+ of `fmrest-core` and [Spyke](https://github.com/balvig/spyke).
26
+ * `fmrest-core`, providing the core
27
+ [Faraday](https://github.com/lostisland/faraday) connection builder, session
28
+ management, and other core utilities.
29
+ * `fmrest-rails`, providing Rails integration.
30
+
31
+ In addition, the optional `fmrest-cloud` gem adds support for FileMaker Cloud.
32
+ See the [main document on connecting to FileMaker
33
+ Cloud](docs/FileMakerCloud.md).
34
+
35
+ ## Installation
36
+
37
+ In your Gemfile:
38
+
39
+ ```ruby
40
+ gem 'fmrest'
41
+
42
+ # Optional: if your files are hosted on FileMaker Cloud
43
+ gem 'fmrest-cloud'
44
+ ```
45
+
46
+ If you're using Rails you can now run:
47
+
48
+ ```
49
+ rails generate fmrest:config
50
+ ```
51
+
52
+ ## Simple example
53
+
54
+ ```ruby
55
+ # A Layout model connecting to the "Honeybees Web" FileMaker layout
56
+ class Honeybee < FmRest::Layout("Honeybees Web")
57
+ # Connection settings
58
+ self.fmrest_config = {
59
+ host: "…",
60
+ database: "…",
61
+ username: "…",
62
+ password: "…"
63
+ }
64
+
65
+ # Mapped attributes
66
+ attributes name: "Bee Name", age: "Bee Age", created_on: "Created On"
67
+
68
+ # Portal associations
69
+ has_portal :tasks
70
+
71
+ # File containers
72
+ container :photo, field_name: "Bee Photo"
73
+
74
+ # Scopes
75
+ scope :can_legally_fly, -> { query(age: ">18") }
76
+
77
+ # Client-side validations
78
+ validates :name, presence: true
79
+
80
+ # Callbacks
81
+ before_save :set_created_on
82
+
83
+ private
84
+
85
+ def set_created_on
86
+ self.created_on = Date.today
87
+ end
88
+ end
89
+
90
+ # Find a record by id
91
+ bee = Honeybee.find(9)
92
+
93
+ bee.name = "Hutch"
94
+
95
+ # Add a new record to portal
96
+ bee.tasks.build(urgency: "Today")
97
+
98
+ bee.save
99
+ ```
100
+
101
+ In case you don't want the ORM features (i.e. you only need authentication and
102
+ JSON parsing, and are comfortable writing the API requests manually without the
103
+ ORM overhead) you can use the Faraday connection provided by `fmrest-core`.
104
+ See the [main document on using the base
105
+ connection](docs/BaseConnectionUsage.md) for more.
106
+
107
+ ## Connection settings
108
+
109
+ The minimum required connection settings are `:host`, `:database`, `:username`
110
+ and `:password`, but fmrest-ruby has many other options you can pass when
111
+ setting up a connection (see [full list](#full-list-of-available-options) below).
112
+
113
+ `:ssl` and `:proxy` are forwarded to the underlying
114
+ [Faraday](https://github.com/lostisland/faraday) connection. You can use this
115
+ to, for instance, disable SSL verification:
116
+
117
+ ```ruby
118
+ {
119
+ host: "…",
120
+
121
+ ssl: { verify: false },
122
+ proxy: "http://user:password@proxy.host:4321"
123
+ }
124
+ ```
125
+
126
+ You can also pass a `:log` option for basic request logging, see the section on
127
+ [Logging](#Logging) below.
128
+
129
+ ### Full list of available options
130
+
131
+ Option | Description | Format | Default
132
+ --------------------|--------------------------------------------|-----------------------------|--------
133
+ `:host` | Hostname with optional port, e.g. `example.com:9000` | String | None
134
+ `:database` | The name of the database to connect to | String | None
135
+ `:username` | A Data API-ready account | String | None
136
+ `:password` | Your password | String | None
137
+ `:account_name` | Alias of `:username` | String | None
138
+ `:ssl` | SSL options to be forwarded to Faraday | [Faraday SSL options](https://www.rubydoc.info/gems/faraday/Faraday/SSLOptions) hash | None
139
+ `:proxy` | Proxy URI, e.g. `http://user:password@proxy.host:4321` | String | None
140
+ `:log` | Log JSON responses to STDOUT | Boolean | `false`
141
+ `:log_level` | Which log level to log into | Values accepted by `Logger#level=` | `:debug`
142
+ `:coerce_dates` | See section on [date fields](#date-fields-and-timezones) | Boolean \| `:hybrid` \| `:full` | `false`
143
+ `:date_format` | Date parsing format | String (FM date format) | `"MM/dd/yyyy"`
144
+ `:timestamp_format` | Timestmap parsing format | String (FM date format) | `"MM/dd/yyyy HH:mm:ss"`
145
+ `:time_format` | Time parsing format | String (FM date format) | `"HH:mm:ss"`
146
+ `:timezone` | The timezone for the FM server | `:local` \| `:utc` \| `nil` | `nil`
147
+ `:autologin` | Whether to automatically start Data API sessions | Boolean | `true`
148
+ `:token` | Used to manually provide a session token (e.g. if `:autologin` is `false`) | String | None
149
+ `:fmid_token` | Claris ID token (only needed if manually obtaining the token) | String | None
150
+ `:cloud` | Specifies whether the host is using FileMaker Cloud | `:auto` \| Boolean | `:auto`
151
+ `:cognito_client_id`| Overwrites the hardcoded FileMaker Cloud Cognito Client ID | String | None
152
+ `:cognito_pool_id` | Overwrites the hardcoded FileMaker Cloud Cognito Pool ID | String | None
153
+ `:aws_region` | Overwrites the hardcoded FileMaker Cloud AWS Region | String | None
154
+
155
+ ### Default connection settings
156
+
157
+ If you're only connecting to a single FM database you can configure it globally
158
+ through `FmRest.default_connection_settings=`. E.g.:
159
+
160
+ ```ruby
161
+ FmRest.default_connection_settings = {
162
+ host: "…",
163
+ database: "…",
164
+ username: "…",
165
+ password: "…"
166
+ }
167
+ ```
168
+
169
+ These settings will be used by default by `FmRest::Layout` models whenever you
170
+ don't set `fmrest_config=` explicitly, as well as by
171
+ `FmRest::V1.build_connection` in case you're setting up your Faraday connection
172
+ manually.
173
+
174
+ ## Session token store
175
+
176
+ fmrest-ruby includes a number of options for storing session tokens:
177
+
178
+ * Memory
179
+ * ActiveRecord
180
+ * Redis
181
+ * Moneta
182
+
183
+ See the [main document on token stores](docs/TokenStore.md) for detailed info
184
+ on how to set up each store.
185
+
186
+ ## Date fields and timezones
187
+
188
+ fmrest-ruby has automatic detection and coercion of date fields to and from
189
+ Ruby date/time objects. Basic timezone support is also provided.
190
+
191
+ See the [main document on date fields](docs/DateFields.md) for more info.
192
+
193
+ ## ActiveRecord-like ORM (fmrest-spyke)
194
+
195
+ [Spyke](https://github.com/balvig/spyke) is an ActiveRecord-like gem for
196
+ building REST ORM models. fmrest-ruby uses it to build its ORM features,
197
+ bundled in the `fmrest-spyke` gem (already included if you're using the
198
+ `fmrest` gem).
199
+
200
+ To create a model you can inherit directly from `FmRest::Layout` (itself a
201
+ subclass of `Spyke::Base`).
202
+
203
+ ```ruby
204
+ class Honeybee < FmRest::Layout
205
+ end
206
+ ```
207
+
208
+ All of Spyke's basic ORM operations work as expected:
209
+
210
+ ```ruby
211
+ bee = Honeybee.new
212
+
213
+ bee.name = "Hutch"
214
+ bee.save # POST request (creates new record)
215
+
216
+ bee.name = "ハッチ"
217
+ bee.save # PATCH request (updates existing record)
218
+
219
+ bee.reload # GET request
220
+
221
+ bee.destroy # DELETE request
222
+
223
+ bee = Honeybee.find(9) # GET request
224
+ ```
225
+
226
+ It's recommended that you read Spyke's documentation for more information on
227
+ these basic features. If you've used ActiveRecord or similar ORM libraries
228
+ you'll find it quite familiar.
229
+
230
+ Notice that `FmRest::Layout` is aliased as `FmRest::Spyke::Base`. Previous
231
+ versions of fmrest-ruby only provided the latter version, so if you're already
232
+ using `FmRest::Spyke::Base` there's no need to rename your classes to
233
+ `FmRest::Layout`, both will continue to work interchangeably.
234
+
235
+ In addition, `FmRest::Layout` extends `Spyke::Base` with the following
236
+ features:
237
+
238
+ ### FmRest::Layout.fmrest_config=
239
+
240
+ This allows you to set Data API connection settings specific to your model
241
+ class:
242
+
243
+ ```ruby
244
+ class Honeybee < FmRest::Layout
245
+ self.fmrest_config = {
246
+ host: "…",
247
+ database: "…",
248
+ username: "…",
249
+ password: "…"
250
+ }
251
+ end
252
+ ```
253
+
254
+ These settings are class-inheritable, so you could create a base class that
255
+ does the initial connection setup and then inherit from it in models using that
256
+ same connection. E.g.:
257
+
258
+ ```ruby
259
+ class ApplicationFmLayout < FmRest::Layout
260
+ self.fmrest_config = { host: "…", database: "…", … }
261
+ end
262
+
263
+ class Honeybee < ApplicationFmLayout
264
+ # This model will use the same connection as ApplicationFmLayout
265
+ end
266
+ ```
267
+
268
+ If `fmrest_config` is not set, your model will try to use
269
+ `FmRest.default_connection_settings` instead.
270
+
271
+ #### Connection settings overlays
272
+
273
+ There may be cases where you want to use a different set of connection settings
274
+ depending on context. For example, if you want to use username and password
275
+ provided by the user in a web application. Since `.fmrest_config` is set at the
276
+ class level, changing the username/password for the model in one context would
277
+ also change it in all other contexts, leading to security issues.
278
+
279
+ To solve this scenario, fmrest-ruby provides a way of defining thread-local,
280
+ reversible connection settings overlays through `.fmrest_config_overlay=`.
281
+
282
+ See the [main document on connection setting overlays](docs/ConfigOverlays.md)
283
+ for details on how it works.
284
+
285
+ ### FmRest::Layout.layout
286
+
287
+ Use `layout` to set the layout name for your model.
288
+
289
+ ```ruby
290
+ class Honeybee < FmRest::Layout
291
+ layout "Honeybees Web"
292
+ end
293
+ ```
294
+
295
+ Alternatively, if you're inheriting from `FmRest::Layout` directly you can set
296
+ the layout name in the class definition line:
297
+
298
+ ```ruby
299
+ class Honeybee < FmRest::Layout("Honeybees Web")
300
+ ```
301
+
302
+ Note that you only need to manually set the layout name if the name of the
303
+ class and the name of the layout differ, otherwise fmrest-ruby will just use
304
+ the name of the class.
305
+
306
+ ### FmRest::Layout.request_auth_token
307
+
308
+ Requests a Data API session token using the connection settings in
309
+ `fmrest_config` and returns it if successful, otherwise returns `false`.
310
+
311
+ You normally don't need to use this method as fmrest-ruby will automatically
312
+ request and store session tokens for you (provided that `:autologin` is
313
+ `true` in the connection settings, which it is by default).
314
+
315
+ ### FmRest::Layout.logout
316
+
317
+ Use `.logout` to log out from the database session (you may call it on any
318
+ model that uses the database session you want to log out from).
319
+
320
+ ```ruby
321
+ Honeybee.logout
322
+ ```
323
+
324
+ ### Mapped FmRest::Layout.attributes
325
+
326
+ Spyke allows you to define your model's attributes using `attributes`, however
327
+ sometimes FileMaker's field names aren't very Ruby-ORM-friendly, especially
328
+ since they may sometimes contain spaces and other special characters, so
329
+ fmrest-ruby extends `attributes`' functionality to allow you to map
330
+ Ruby-friendly attribute names to FileMaker field names. E.g.:
331
+
332
+ ```ruby
333
+ class Honeybee < FmRest::Layout
334
+ attributes first_name: "First Name", last_name: "Last Name"
335
+ end
336
+ ```
337
+
338
+ You can then simply use the pretty attribute names whenever working with your
339
+ model and they will get mapped to their FileMaker fields:
340
+
341
+ ```ruby
342
+ bee = Honeybee.find(1)
343
+
344
+ bee.first_name # => "Princess"
345
+ bee.last_name # => "Buzz"
346
+
347
+ bee.first_name = "Queen"
348
+
349
+ bee.attributes # => { "First Name": "Queen", "Last Name": "Buzz" }
350
+ ```
351
+
352
+ ### FmRest::Layout.has_portal
353
+
354
+ You can define portal associations on your model wth `has_portal`, as such:
355
+
356
+ ```ruby
357
+ class Honeybee < FmRest::Layout
358
+ has_portal :flowers
359
+ end
360
+
361
+ class Flower < FmRest::Layout
362
+ attributes :color, :species
363
+ end
364
+ ```
365
+
366
+ See the [main document on portal associations](docs/Portals.md) for details.
367
+
368
+ ### Dirty attributes
369
+
370
+ fmrest-ruby includes support for ActiveModel's Dirty mixin out of the box,
371
+ providing methods like:
372
+
373
+ ```ruby
374
+ bee = Honeybee.new
375
+
376
+ bee.changed? # => false
377
+
378
+ bee.name = "Maya"
379
+
380
+ bee.changed? # => true
381
+
382
+ bee.name_changed? # => true
383
+ ```
384
+
385
+ fmrest-ruby uses the Dirty functionality to only send changed attributes back
386
+ to the server on save.
387
+
388
+ You can read more about [ActiveModel's Dirty in Rails
389
+ Guides](https://guides.rubyonrails.org/active_model_basics.html#dirty).
390
+
391
+ ### Query API
392
+
393
+ Since Spyke is API-agnostic it only provides a wide-purpose `.where` method for
394
+ passing arbitrary parameters to the REST backend. fmrest-ruby however is well
395
+ aware of its backend API, so it extends Spkye models with a bunch of useful
396
+ querying methods: `.query`, `.match`, `.omit`, `.limit`, `.offset`, `.sort`,
397
+ `.portal`, `.script`, etc.
398
+
399
+ See the [main document on querying](docs/Querying.md) for detailed information
400
+ on the query API methods.
401
+
402
+ ### Finding records in batches
403
+
404
+ Sometimes you want to iterate over a very large number of records to do some
405
+ processing, but requesting them all at once would result in one huge request to
406
+ the Data API, and loading too many records in memory all at once.
407
+
408
+ To mitigate this problem you can use `.find_in_batches` and `.find_each`.
409
+
410
+ See the [main document on finding in batches](docs/FindInBatches.md) for
411
+ detailed information on how those work.
412
+
413
+ ### Container fields
414
+
415
+ You can define container fields on your model class with `container`:
416
+
417
+ ```ruby
418
+ class Honeybee < FmRest::Layout
419
+ container :photo, field_name: "Beehive Photo ID"
420
+ end
421
+ ```
422
+
423
+ See the [main document on container fields](docs/ContainerFields.md) for
424
+ details on how to use it.
425
+
426
+ ### Script execution
427
+
428
+ The FM Data API allows running scripts as part of many types of requests, and
429
+ `fmrest-spyke` provides mechanisms for all of them.
430
+
431
+ See the [main document on script execution](docs/ScriptExecution.md) for
432
+ details.
433
+
434
+ ### Setting global field values
435
+
436
+ You can call `.set_globals` on any `FmRest::Layout` model to set global
437
+ field values on the database that model is configured for.
438
+
439
+ See the [main document on setting global field values](docs/GlobalFields.md)
440
+ for details.
441
+
442
+ ### Rescuable mixin
443
+
444
+ Sometimes you may want to handle Data API errors at the model level. For such
445
+ cases fmrest-ruby provides an off-by-default mixin called `Rescuable` that
446
+ provides convenience macros for that. If you've used Ruby on Rails you may be
447
+ familiar with its syntax from controllers. E.g.
448
+
449
+ ```ruby
450
+ class BeeBase < FmRest::Layout
451
+ include FmRest::Spyke::Model::Rescuable
452
+
453
+ rescue_from FmRest::APIError::SystemError, with: :notify_admin_of_system_error
454
+
455
+ def self.notify_admin_of_system_error(e)
456
+ # Shoot an email to the FM admin...
457
+ end
458
+ end
459
+ ```
460
+
461
+ Since `Rescuable` uses `ActiveSupport::Rescuable` internally, you may want to
462
+ check [Rails'
463
+ documentation](https://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html)
464
+ too for details on how it works.
465
+
466
+ One caveat of using `rescue_from` is that it always catches exceptions at the
467
+ class level, so if you pass a method name to `with:` that method has to be a
468
+ class method. Also note that this will only catch exceptions raised during an
469
+ API call to the Data API server (in other words, only on actions that perform
470
+ an HTTP request).
471
+
472
+ ## Logging
473
+
474
+ If using `fmrest-spyke` with Rails then pretty log output will be set up for
475
+ you automatically by Spyke (see [their
476
+ README](https://github.com/balvig/spyke#log-output)).
477
+
478
+ You can also enable simple Faraday logging of raw requests (useful for
479
+ debugging) by passing `log: true` in the options hash for either
480
+ `FmRest.default_connection_settings=` or your models' `fmrest_config=`, e.g.:
481
+
482
+ ```ruby
483
+ FmRest.default_connection_settings = {
484
+ host: "…",
485
+
486
+ log: true
487
+ }
488
+
489
+ # Or in your model
490
+ class LoggyBee < FmRest::Layout
491
+ self.fmrest_config = {
492
+ host: "…",
493
+
494
+ log: true
495
+ }
496
+ end
497
+ ```
498
+
499
+ You can also pass `log_level` to connection settings to change the severity of
500
+ log output (defaults to `:debug`).
501
+
502
+ By default fmrest-ruby logs to STDOUT or to Rails' logger object if available.
503
+ You can change this by providing your own logger object to `FmRest.logger=`:
504
+
505
+ ```ruby
506
+ FmRest.logger = Logger.new("fmrest.log")
507
+ ```
508
+
509
+ If you need to set up more complex logging for your models you can use the
510
+ `faraday` block inside your class to inject your own logger middleware into the
511
+ Faraday connection, e.g.:
512
+
513
+ ```ruby
514
+ class LoggyBee < FmRest::Layout
515
+ faraday do |conn|
516
+ conn.response :logger, MyApp.logger, bodies: true
517
+ end
518
+ end
519
+ ```
520
+
521
+ ## Gotchas
522
+
523
+ Read about unexpected scenarios in the [gotchas doc](docs/Gotchas.md).
524
+
525
+ ## API implementation completeness table
526
+
527
+ FM Data API reference: https://help.claris.com/en/data-api-guide/
528
+
529
+ | FM 19 Data API feature | Supported by basic connection | Supported by FmRest::Layout |
530
+ |-------------------------------------|-------------------------------|-----------------------------|
531
+ | Log in using HTTP Basic Auth | Yes | Yes |
532
+ | Log in using OAuth | No | No |
533
+ | Log in to an external data source | No | No |
534
+ | Log in using Claris ID account (FileMaker Cloud) | Yes | Yes |
535
+ | Log out | Yes | Yes |
536
+ | Get product information | Manual* | No |
537
+ | Get database names | Manual* | No |
538
+ | Get script names | Manual* | No |
539
+ | Get layout names | Manual* | No |
540
+ | Get layout metadata | Manual* | No |
541
+ | Create a record | Manual* | Yes |
542
+ | Edit a record | Manual* | Yes |
543
+ | Duplicate a record | Manual* | No |
544
+ | Delete a record | Manual* | Yes |
545
+ | Edit portal records | Manual* | Yes |
546
+ | Get a single record | Manual* | Yes |
547
+ | Get a range of records | Manual* | Yes |
548
+ | Get container data | Manual* | Yes |
549
+ | Upload container data | Manual* | Yes |
550
+ | Perform a find request | Manual* | Yes |
551
+ | Set global field values | Manual* | Yes |
552
+ | Run a script | Manual* | Yes |
553
+ | Run a script with another request | Manual* | Yes |
554
+
555
+ \* You can manually supply the URL and JSON to a `FmRest` connection.
556
+
557
+ ## Supported Ruby versions
558
+
559
+ fmrest-ruby is [tested against](https://github.com/beezwax/fmrest-ruby/actions?query=workflow%3ACI)
560
+ Ruby 2.6 through 3.1.
561
+
562
+ ## Gem development
563
+
564
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run
565
+ `bundle exec rspec` to run the specs. You can also run `bin/console` for an
566
+ interactive prompt that will allow you to experiment (it will auto-load all
567
+ fixtures in spec/fixtures).
568
+
569
+ To install all gems onto your local machine, run
570
+ `bundle exec rake all:install`. To release a new version, update the version
571
+ number in `lib/fmrest/version.rb`, and then run `bundle exec rake all:release`,
572
+ which will create a git tag for the version, push git commits and tags, and
573
+ push the `.gem` files to [rubygems.org](https://rubygems.org).
574
+
575
+ ## Disclaimer
576
+
577
+ This project is not sponsored by or otherwise affiliated with Claris
578
+ International Inc., an Apple Inc. subsidiary. FileMaker is a trademark of
579
+ Claris International Inc., registered in the U.S. and other countries.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fmrest"
4
+
5
+ module Rails
6
+ module FmRest
7
+ class Railtie < Rails::Railtie
8
+ initializer "fmrest.load_config" do
9
+ ::FmRest.default_connection_settings = Rails.application.config_for("fmrest")
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fmrest"
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is capitalized differently (Fmrest vs FmRest) on purpose, so the
4
+ # generator can be found as "fmrest:config"
5
+ module Fmrest
6
+ module Generators
7
+ class ConfigGenerator < Rails::Generators::Base
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ def copy_config_file
11
+ copy_file "fmrest.yml", "config/fmrest.yml"
12
+ end
13
+
14
+ def copy_initializer_file
15
+ copy_file "fmrest_initializer.rb", "config/initializers/fmrest.rb"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ development:
2
+ host:
3
+ database:
4
+ username:
5
+ password:
6
+
7
+ # Additional options
8
+ #
9
+ # log: false
10
+ #
11
+ # ssl:
12
+ # verify: true
13
+
14
+ test:
15
+ host:
16
+ database:
17
+ username:
18
+ password:
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Use ActiveRecord token store
4
+ FmRest.token_store = FmRest::TokenStore::ActiveRecord
5
+
6
+ # Use ActiveRecord token store with custom table name
7
+ # FmRest.token_store = FmRest::TokenStore::ActiveRecord.new(table_name: "my_token_store")
8
+
9
+ # Use Redis token store (requires redis gem)
10
+ # FmRest.token_store = FmRest::TokenStore::Redis
11
+
12
+ # Use Redis token store with custom prefix
13
+ # FmRest.token_store = FmRest::TokenStore::Redis.new(prefix: "my-fmrest-token:")
14
+
15
+ # Use Moneta token store (requires moneta gem)
16
+ # FmRest.token_store = FmRest::TokenStore::Moneta.new(backend: )
17
+
18
+ # Use Memory token store (not suitable for production)
19
+ # FmRest.token_store = FmRest::TokenStore::Memory
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is capitalized differently (Fmrest vs FmRest) on purpose, so the
4
+ # generator can be found as "fmrest:config"
5
+ module Fmrest
6
+ module Generators
7
+ class ModelGenerator < Rails::Generators::NamedBase
8
+ source_root File.expand_path('templates', __dir__)
9
+
10
+ def create_model_file
11
+ template "model.rb", "app/models/#{file_name}.rb"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= class_name %> < FmRest::Layout
4
+ # Uncomment if your layout name isn't "<%= class_name %>", or delete:
5
+ # layout "<%= plural_name %>"
6
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fmrest-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.22.0
5
+ platform: ruby
6
+ authors:
7
+ - Pedro Carbajal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-06-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fmrest-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.22.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.22.0
27
+ description: fmrest-rails provides Rails integration for the fmrest gem.
28
+ email:
29
+ - pedro_c@beezwax.net
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".yardopts"
35
+ - CHANGELOG.md
36
+ - LICENSE.txt
37
+ - README.md
38
+ - lib/fmrest-rails.rb
39
+ - lib/fmrest/railtie.rb
40
+ - lib/generators/fmrest/config/config_generator.rb
41
+ - lib/generators/fmrest/config/templates/fmrest.yml
42
+ - lib/generators/fmrest/config/templates/fmrest_initializer.rb
43
+ - lib/generators/fmrest/model/model_generator.rb
44
+ - lib/generators/fmrest/model/templates/model.rb
45
+ homepage: https://github.com/beezwax/fmrest-ruby
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: '0'
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubygems_version: 3.3.3
65
+ signing_key:
66
+ specification_version: 4
67
+ summary: Rails ties and generators for fmrest gem
68
+ test_files: []