airrecord 0.2.3 → 0.2.4

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