airtable2 0.2.2 → 0.2.3

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
2
  SHA256:
3
- metadata.gz: 8f8968193253823a000c9f38c14185208b89a4dfd77d9ff6ab0a5b5f8b3f595e
4
- data.tar.gz: 06c31cfbcc19f156ab7e498e7e6b6f9f0ca4b749aecb523124f85df7d8a452c2
3
+ metadata.gz: 32bae2cc155c84b948c193c8ea5677288ea7123aeded90f6e6121ba196d0a4c7
4
+ data.tar.gz: 8efc8479bf004389e25aee1bdc8b88b60dfbc395078dfa4935f4a65afa93bbe4
5
5
  SHA512:
6
- metadata.gz: 6bbbc8e341a9a16969df15e605d0e379138915066968abd3581b635d6bf66349526ae7f88d483384a5248f6f72c97f1f85d32e2a4a7e3e49c223f339d07cedc0
7
- data.tar.gz: f8f0c2a7f3400519a07082a7c1640ae80947c7d4c4143d6b0d82e50068c01176d0f3aaeeeee392d9926647574f65185fc69382a147fa68b0bad4c2603dc2f59d
6
+ metadata.gz: 9f0993c56aa18abf1fc80089ebf8b08d377ff70476c04b4df619dd6637a4439bf034a0af2b8f90660244464ceeefc137fd836cd99493b00415ea7108cead000b
7
+ data.tar.gz: b1b30151a67ff2ce1f2eb479327ef1a959fa4ca9d671ecd33553d3a75c746f1193010e5d3e1ab457cfbd3ca9e25d385a2c85cc5d850e1a3b2766ddfd65160647
data/README.md CHANGED
@@ -41,12 +41,15 @@ and its tables
41
41
  @tables = @base.tables
42
42
  ```
43
43
 
44
- and a table's records, so you can navigate the has_many chain the way God intended:
44
+ and a table's records, so you can navigate the belongs_to/has_many relationships the way God intended:
45
45
 
46
46
  ```ruby
47
- @client.bases.first.tables.first.records.first
47
+ @record = @client.bases.first.tables.first.records.first
48
+ @base = @record.table.base
48
49
  ```
49
50
 
51
+ Note that objects' child records are memoized to avoid unnecessary API calls. If sensitive to stale data, be sure to use the objects instantiated most recently.
52
+
50
53
  ### Manipulating Tables
51
54
 
52
55
  Create a new table with:
@@ -71,10 +74,10 @@ Once you have access to a table from above, we can query a set of records in the
71
74
 
72
75
  ### Inserting Records
73
76
 
74
- A single record or an array of records can be inserted using the `add_records` method on a table (max 10 at a time):
77
+ A single record or an array of records can be inserted using the `create_records` method on a table (max 10 at a time):
75
78
 
76
79
  ```ruby
77
- @table.add_records({ 'Name': 'name value', 'Age': 35 })
80
+ @table.create_records({ 'Name': 'name value', 'Age': 35 })
78
81
  ```
79
82
 
80
83
  ### Deleting Records
data/airtable.gemspec CHANGED
@@ -30,5 +30,7 @@ Gem::Specification.new do |spec|
30
30
  spec.add_development_dependency 'rubocop-performance'
31
31
  spec.add_development_dependency 'rubocop-rake'
32
32
  spec.add_development_dependency 'webmock'
33
+
33
34
  spec.metadata['rubygems_mfa_required'] = 'true'
35
+ spec.metadata['github_repo'] = 'ssh://github.com/aseroff/airtable-ruby'
34
36
  end
data/lib/airtable/base.rb CHANGED
@@ -2,14 +2,15 @@
2
2
 
3
3
  # Object corresponding to an Airtable Base
4
4
  class Airtable::Base < Airtable::Resource
5
- def initialize(token, id)
5
+ def initialize(token, id, tables = nil)
6
6
  super(token)
7
7
  @id = id
8
+ @tables = tables
8
9
  end
9
10
 
10
- # Expects {name:,description:,fields:[]}
11
- # @see https://airtable.com/developers/web/api/create-table
11
+ # @param table_data [Hash] Payload for table creation. Expects {name:,description:,fields:[]}
12
12
  # @return [Airtable::Table]
13
+ # @see https://airtable.com/developers/web/api/create-table
13
14
  def create_table(table_data)
14
15
  response = self.class.post("#{base_url}/tables",
15
16
  body: table_data.to_json).parsed_response
@@ -19,17 +20,20 @@ class Airtable::Base < Airtable::Resource
19
20
  Airtable::Table.new @token, @id, response
20
21
  end
21
22
 
23
+ # @return [Array<Airtable::Table>]
22
24
  # @see https://airtable.com/developers/web/api/get-base-schema
23
- # @return [Array]<Airtable::Table>
24
25
  def tables
25
- response = self.class.get("#{base_url}/tables")
26
+ @tables ||= begin
27
+ response = self.class.get("#{base_url}/tables")
26
28
 
27
- check_and_raise_error(response)
29
+ check_and_raise_error(response)
28
30
 
29
- response['tables'].map { Airtable::Table.new(@token, @id, _1) }
31
+ response['tables'].map { Airtable::Table.new(@token, @id, _1['id'], _1) }
32
+ end
30
33
  end
31
34
 
32
35
  # Instantiate table in base
36
+ # @param table_id [String] ID of table
33
37
  # @return [Airtable::Table]
34
38
  def table(table_id)
35
39
  Airtable::Table.new(@token, @id, table_id)
@@ -2,8 +2,8 @@
2
2
 
3
3
  # Client carrying authorization token
4
4
  class Airtable::Client < Airtable::Resource
5
+ # @return [Array<Airtable::Base>]
5
6
  # @see https://airtable.com/developers/web/api/list-bases
6
- # @return [Array]<Airtable::Base>
7
7
  def bases
8
8
  response = self.class.get('/v0/meta/bases').parsed_response
9
9
 
@@ -12,22 +12,22 @@ class Airtable::Client < Airtable::Resource
12
12
  response['bases'].map { Airtable::Base.new(@token, _1['id']) }
13
13
  end
14
14
 
15
- # @see https://airtable.com/developers/web/api/create-base
16
- # def create_base(base_data)
17
- # response = self.class.post('/v0/meta/bases'
18
- # body: base_data.to_json).parsed_response
19
- # check_and_raise_error(response)
20
- # Airtable::Base.new @token, response
21
- # end
15
+ # Instantiate workspace
16
+ # @param workspace_id [String] ID of workspace
17
+ # @return [Airtable::Workspace]
18
+ def workspace(workspace_id)
19
+ Airtable::Workspace.new(@token, workspace_id)
20
+ end
22
21
 
23
22
  # Instantiate base
23
+ # @param base_id [String] ID of base
24
24
  # @return [Airtable::Base]
25
25
  def base(base_id)
26
26
  Airtable::Base.new(@token, base_id)
27
27
  end
28
28
 
29
+ # @return [Hash] User's data based on token
29
30
  # @see https://airtable.com/developers/web/api/get-user-id-scopes
30
- # @return [Hash]
31
31
  def whoami
32
32
  response = self.class.get('/v0/meta/whoami').parsed_response
33
33
 
@@ -2,14 +2,44 @@
2
2
 
3
3
  # Object corresponding to an Airtable Record
4
4
  class Airtable::Record < Airtable::Resource
5
- attr_reader :fields
6
-
7
- def initialize(token, base_id, table_id, api_response)
5
+ def initialize(token, base_id, table_id, id, data = nil)
8
6
  super(token)
9
7
  @base_id = base_id
10
8
  @table_id = table_id
11
- api_response.deep_symbolize_keys.each do |key, value|
12
- instance_variable_set(:"@#{key}", value)
9
+ @id = id
10
+ @data = data
11
+ end
12
+
13
+ # Return record data, retrieve if not present
14
+ # @return [Hash]
15
+ # @see https://airtable.com/developers/web/api/get-record
16
+ def data
17
+ @data ||= begin
18
+ response = self.class.get(record_url).parsed_response
19
+
20
+ check_and_raise_error(response)
21
+
22
+ response
13
23
  end
14
24
  end
25
+
26
+ # Instantiate record's table
27
+ # @return [Airtable::Table]
28
+ def table = Airtable::Table.new(token, @base_id, @table_id)
29
+
30
+ # @return [Airtable::Record]
31
+ # @see https://airtable.com/developers/web/api/update-record
32
+ def update(record_data)
33
+ response = self.class.patch(record_url,
34
+ body: { fields: record_data }.to_json).parsed_response
35
+
36
+ check_and_raise_error(response)
37
+
38
+ Airtable::Record.new @token, @base_id, @table_id, response['id'], response
39
+ end
40
+
41
+ protected
42
+
43
+ # Endpoint for records
44
+ def record_url = "/v0/#{@base_id}/#{@table_id}/#{@id}"
15
45
  end
@@ -4,45 +4,55 @@
4
4
  class Airtable::Table < Airtable::Resource
5
5
  attr_reader :name
6
6
 
7
- def initialize(token, base_id, api_response)
7
+ def initialize(token, base_id, id, data = nil)
8
8
  super(token)
9
9
  @base_id = base_id
10
- api_response.deep_symbolize_keys.each do |key, value|
11
- instance_variable_set(:"@#{key}", value)
12
- end
10
+ @id = id
11
+ @data = data
13
12
  end
14
13
 
15
- # @see https://airtable.com/developers/web/api/list-records
14
+ # Return table model, retrieve if not present
15
+ # @return [Hash]
16
+ # @see https://airtable.com/developers/web/api/get-base-schema
17
+ def data = @data ||= base.tables.find { _1.id == @id }.data
18
+
19
+ # Instantiate table's base
20
+ # @return [Airtable::Base]
21
+ def base = Airtable::Base.new(token, @base_id)
22
+
16
23
  # @return [Array<Airtable::Record>]
24
+ # @see https://airtable.com/developers/web/api/list-records
17
25
  def records
18
- response = self.class.get(table_url)
26
+ @records ||= begin
27
+ response = self.class.get(table_url)
19
28
 
20
- check_and_raise_error(response)
29
+ check_and_raise_error(response)
21
30
 
22
- response['records'].map { Airtable::Record.new(@token, @base_id, @table_id, _1) }
31
+ response['records'].map { Airtable::Record.new(@token, @base_id, @id, _1['id'], _1) }
32
+ end
23
33
  end
24
34
 
25
35
  # Instantiate record in table
26
- # @return [Airtable::Table]
27
- def record(record_id)
28
- Airtable::Table.new(@token, @base_id, @id, record_id)
29
- end
36
+ # @param record_id [String] ID of record
37
+ # @return [Airtable::Record]
38
+ def record(record_id) = Airtable::Record.new(@token, @base_id, @id, record_id)
30
39
 
31
- # @see https://airtable.com/developers/web/api/update-table
32
40
  # @return [Airtable::Table]
41
+ # @see https://airtable.com/developers/web/api/update-table
33
42
  def update(table_data)
34
43
  response = self.class.patch("/v0/meta/bases/#{@base_id}/tables/#{@id}",
35
44
  body: table_data.to_json).parsed_response
36
45
 
37
46
  check_and_raise_error(response)
38
47
 
39
- Airtable::Table.new @token, @base_id, response
48
+ Airtable::Table.new @token, @base_id, response['id'], response
40
49
  end
41
50
 
42
- # @note API maximum of 10 records at a time
43
- # @see https://airtable.com/developers/web/api/create-records
51
+ # @param [Array] Record objects to create
44
52
  # @return [Array<Airtable::Record>]
45
- def add_records(records)
53
+ # @see https://airtable.com/developers/web/api/create-records
54
+ # @note API maximum of 10 records at a time
55
+ def create_records(records)
46
56
  response = self.class.post(table_url,
47
57
  body: { records: Array(records).map { |fields| { fields: } } }.to_json).parsed_response
48
58
 
@@ -51,9 +61,10 @@ class Airtable::Table < Airtable::Resource
51
61
  response['records'].map { Airtable::Record.new(@token, @base_id, @id, _1) }
52
62
  end
53
63
 
54
- # @note API maximum of 10 records at a time
55
- # @see https://airtable.com/developers/web/api/delete-multiple-records
64
+ # @param [Array] IDs of records to delete
56
65
  # @return [Array] Deleted record ids
66
+ # @see https://airtable.com/developers/web/api/delete-multiple-records
67
+ # @note API maximum of 10 records at a time
57
68
  def delete_records(record_ids)
58
69
  params = Array(record_ids).compact.map { "records[]=#{_1}" }.join('&')
59
70
  response = self.class.delete("#{table_url}?#{params}").parsed_response
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module Airtable
5
- VERSION = '0.2.2'
5
+ VERSION = '0.2.3'
6
6
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Object corresponding to an Airtable Workspace
4
+ class Airtable::Workspace < Airtable::Resource
5
+ def initialize(token, id)
6
+ super(token)
7
+ @id = id
8
+ end
9
+
10
+ # @param base_data [Hash] Payload for base
11
+ # @see https://airtable.com/developers/web/api/create-base
12
+ def create_base(base_data)
13
+ response = self.class.post('/v0/meta/bases',
14
+ body: base_data.merge({ workspaceId: @id }).to_json).parsed_response
15
+
16
+ check_and_raise_error(response)
17
+
18
+ Airtable::Base.new @token, response
19
+ end
20
+ end
data/lib/airtable.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'httparty'
4
- require 'delegate'
5
- require 'active_support/core_ext/hash'
6
4
  require 'json'
7
5
 
8
6
  require 'airtable/version'
@@ -10,5 +8,6 @@ require 'airtable/resource'
10
8
  require 'airtable/record'
11
9
  require 'airtable/table'
12
10
  require 'airtable/base'
11
+ require 'airtable/workspace'
13
12
  require 'airtable/client'
14
13
  require 'airtable/error'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: airtable2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Seroff
@@ -175,11 +175,13 @@ files:
175
175
  - lib/airtable/resource.rb
176
176
  - lib/airtable/table.rb
177
177
  - lib/airtable/version.rb
178
+ - lib/airtable/workspace.rb
178
179
  homepage: https://github.com/aseroff/airtable-ruby
179
180
  licenses:
180
181
  - MIT
181
182
  metadata:
182
183
  rubygems_mfa_required: 'true'
184
+ github_repo: ssh://github.com/aseroff/airtable-ruby
183
185
  post_install_message:
184
186
  rdoc_options: []
185
187
  require_paths:
@@ -195,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
197
  - !ruby/object:Gem::Version
196
198
  version: '0'
197
199
  requirements: []
198
- rubygems_version: 3.5.21
200
+ rubygems_version: 3.5.22
199
201
  signing_key:
200
202
  specification_version: 4
201
203
  summary: For when Airrecord is just too much.