airtable2 0.2.2 → 0.2.3

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
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.