airrecord 0.2.3 → 0.2.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: dc85eb8f47b96d2d03f3c2d8ede44021184acce8
4
- data.tar.gz: 3177b982ce62cbe58dbade3fd5e5e24dbe43bf9d
2
+ SHA256:
3
+ metadata.gz: 0e5fbb9f72ea43cf78e32e2a6dbfb0138b5732f3171cfe4416630b84e26d643e
4
+ data.tar.gz: b232483322295e61cd75a09cb56a04a67e673b01ecd27b8aee551e54b91ee45e
5
5
  SHA512:
6
- metadata.gz: 25d59a038cbd3d619443274a9ddf415767d39f98c46a2f695bad07f60a2d4e4a941325f8957c0f4e938a5d8215c0f2f90578209ce35e24c18268ecd14c6673bd
7
- data.tar.gz: cc387e3388f477a9dd538b3f6970486dbff04feed46644603ff17840225d6474b597a38c32fba69b9be779d0ba1dab2873f0817f907e1261fbb51cea6a6f8d21
6
+ metadata.gz: ce0d4a831cd0e2de8d5725b7ad66298ed061d920ee713b2bb0a54bde1c17e5b123e5edc00760b832c1f36ae2f3586bf1cc218fb4982bea265fbc6703c897d358
7
+ data.tar.gz: 115ab85c06ad0934d11e9f8d1a246a155f374300f60cf4c32019c3624e72794ea01d659464649b440ff793296ac2ce9b757feea3d41644fcf10b33770da10ead
@@ -1,3 +1,7 @@
1
+ # 0.2.4
2
+
3
+ * Don't flag as dirty if change is equal
4
+
1
5
  # 0.2.3
2
6
 
3
7
  * Allow single associations (#12)
data/README.md CHANGED
@@ -134,6 +134,9 @@ Tea.all(filter: '{Country} == "China"')
134
134
 
135
135
  # Retrieve all teas created in the past week
136
136
  Tea.all(filter: "DATETIME_DIFF(CREATED_TIME(), TODAY(), 'days') < 7")
137
+
138
+ # Retrieve all teas that don't have a country defined
139
+ Tea.all(filter: "{Country} == \"\"")
137
140
  ```
138
141
 
139
142
  This filtering can, of course, also be done in Ruby directly after calling
@@ -226,6 +229,39 @@ tea = Tea.find("rec839")
226
229
  tea.destroy # deletes record
227
230
  ```
228
231
 
232
+ ### File Uploads
233
+
234
+ Airtable's API requires you to have uploaded your file to an intermediary and
235
+ providing the URL. Unfortunately, it does not allow uploading directly.
236
+
237
+ ```ruby
238
+ word = World.find("cantankerous")
239
+ word["Pronounciation"] = [{url: "https://s3.ca-central-1.amazonaws.com/word-pronunciations/cantankerous.mp3}]
240
+ word.save
241
+ ```
242
+
243
+ S3 is a good place to upload files for Airtable. Airrecord does not support this
244
+ directly, but the snippet below may be helpful:
245
+
246
+ ```ruby
247
+ # Add this to your gemfile
248
+ # Full docs at https://docs.aws.amazon.com/sdkforruby/api/Aws/S3/Client.html
249
+ require 'aws-sdk-s3'
250
+
251
+ Aws.config.update(
252
+ credentials: Aws::Credentials.new(access_key, secret_key) # obtain from AWS
253
+ region: 'ca-central-1', # region
254
+ )
255
+
256
+ s3 = Aws::S3::Client.new
257
+ s3.put_object({
258
+ body: File.open("cantankerous.mp3"), # IO object
259
+ bucket: 'word-pronunciations',
260
+ key: 'cantankerous.mp3',
261
+ acl: "public-read",
262
+ })
263
+ ```
264
+
229
265
  ### Associations
230
266
 
231
267
  Airrecord supports managing associations between tables by linking
@@ -305,6 +341,54 @@ and _only_ if the column was set. If it's `nil`, it will not exist. That means
305
341
  if you want to set column that has a `nil` value for a column type, you'll have
306
342
  to fully type it out.
307
343
 
344
+ ### Production Middlewares
345
+
346
+ For production use-cases, it's worth considering adding retries and circuit
347
+ breakers to Airrecord. This is _not_ enabled by default. Airrecord uses the
348
+ Faraday gem for HTTP. Similar to Rack, you can add middlewares to provide
349
+ reusable logic for making HTTP requests.
350
+
351
+ #### Configuring Retries
352
+
353
+ Refer to the documentation for [all configuration
354
+ options](http://www.rubydoc.info/gems/faraday/0.9.2/Faraday/Request/Retry).
355
+
356
+ ```ruby
357
+ Airrecord::Table.client.connection.request :retry,
358
+ max: 5, interval: 1, interval_randomness: 2, backoff_factor: 2,
359
+ exceptions: [...] # It's suggested to be explicit here instead of relying on defaults
360
+ ```
361
+
362
+ If you are running background scripts or workers with the sole purpose of
363
+ communicating with Airtable, it may be worth retrying on failures. Note that
364
+ this may cause the process to sleep for many seconds, so choose your values
365
+ carefully.
366
+
367
+ The `Net::HTTP` library that Faraday uses behind the scenes by default has
368
+ opaque exceptions. If you choose to go beyond retrying on timeouts (as is
369
+ provided by default by the Retry middleware), I suggest referring to a complete
370
+ list of `Net::HTTP` exceptions, such as [this
371
+ one](https://github.com/Shopify/semian/blob/master/lib/semian/net_http.rb#L35-L44).
372
+
373
+ ### Circuit Breaker
374
+
375
+ If you're calling Airtable in an application and want to avoid hanging processes
376
+ when Airtable is unavailable, we strongly recommend configuring [circuit
377
+ breakers](https://github.com/Shopify/semian#circuit-breaker). This is a
378
+ mechanism that after `threshold` failures, it'll start failing immediately
379
+ instead of waiting until the timeout. This can avoid outages where all workers
380
+ are hung trying to talk to a service that will never return, instead of serving
381
+ useful fallbacks or requests that don't rely on the service. Failing fast is
382
+ paramount for building reliable systems.
383
+
384
+ You can configure a middleware such as
385
+ [`faraday_middleware-circuit_breaker`](https://github.com/textmaster/faraday_middleware-circuit_breaker):
386
+
387
+ ```ruby
388
+ Airrecord::Table.client.connection.request :circuit_breaker,
389
+ timeout: 20, threshold: 5
390
+ ```
391
+
308
392
  ## Contributing
309
393
 
310
394
  Contributions will be happily accepted in the form of Github Pull Requests!
@@ -90,7 +90,7 @@ module Airrecord
90
90
  alias_method :all, :records
91
91
  end
92
92
 
93
- attr_reader :fields, :column_mappings, :id, :created_at, :updated_fields
93
+ attr_reader :fields, :column_mappings, :id, :created_at, :updated_keys
94
94
 
95
95
  def initialize(fields, id: nil, created_at: nil)
96
96
  @id = id
@@ -126,9 +126,11 @@ module Airrecord
126
126
 
127
127
  def []=(key, value)
128
128
  if fields[key]
129
+ return if fields[key] == value # no-op
129
130
  @updated_keys << key
130
131
  fields[key] = value
131
132
  elsif column_mappings[key]
133
+ return if fields[column_mappings[key]] == value # no-op
132
134
  @updated_keys << column_mappings[key]
133
135
  fields[column_mappings[key]] = value
134
136
  else
@@ -1,3 +1,3 @@
1
1
  module Airrecord
2
- VERSION = "0.2.3"
2
+ VERSION = "0.2.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airrecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Eskildsen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-30 00:00:00.000000000 Z
11
+ date: 2018-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -135,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  version: '0'
136
136
  requirements: []
137
137
  rubyforge_project:
138
- rubygems_version: 2.6.14
138
+ rubygems_version: 2.7.6
139
139
  signing_key:
140
140
  specification_version: 4
141
141
  summary: Airtable client