fmrest-rails 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
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: []