airtable2 0.2.1 → 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: 0fb935ffab4d6e71ec8d1d5b2dc3d333e8e594694efa066cdfb5b9cc2bc127c6
4
- data.tar.gz: 5df0a4d75e41a62e7e37083ebe86a8a907424bdc07b85415fd3322ee97c31564
3
+ metadata.gz: 32bae2cc155c84b948c193c8ea5677288ea7123aeded90f6e6121ba196d0a4c7
4
+ data.tar.gz: 8efc8479bf004389e25aee1bdc8b88b60dfbc395078dfa4935f4a65afa93bbe4
5
5
  SHA512:
6
- metadata.gz: c685dbee77e83356da763e04a4d21cd9045f590790fa1a07a3311fffa5e57f35a46c6ccad9a48763dcf42a6b056ab71421ff8303853f8e50f12e08ea6b03ed50
7
- data.tar.gz: 2a4ca8fc25b2dd248c36f5256ce3c7d57d087ada7048aa41276b20e7deb058e79e60800bcd30b71fe421dfe149fa28038b6240f3f078163c0a0367ef2ca4a0d7
6
+ metadata.gz: 9f0993c56aa18abf1fc80089ebf8b08d377ff70476c04b4df619dd6637a4439bf034a0af2b8f90660244464ceeefc137fd836cd99493b00415ea7108cead000b
7
+ data.tar.gz: b1b30151a67ff2ce1f2eb479327ef1a959fa4ca9d671ecd33553d3a75c746f1193010e5d3e1ab457cfbd3ca9e25d385a2c85cc5d850e1a3b2766ddfd65160647
data/README.md CHANGED
@@ -10,7 +10,7 @@ This is a fork of an abandoned [previous wrapper](https://github.com/nesquena/ai
10
10
 
11
11
  Add this line to your application's Gemfile:
12
12
 
13
- gem 'airtable2', github: 'https://github.com/aseroff/airtable-ruby', branch: 'main'
13
+ gem 'airtable2'
14
14
 
15
15
  And then execute:
16
16
 
@@ -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
@@ -92,6 +95,10 @@ Or as a convenience, you can delete all records with the `dump` method
92
95
  @table.dump
93
96
  ```
94
97
 
98
+ ## Complete documentation
99
+
100
+ YARD-generated documentation is hosted on [GitHub Pages](https://aseroff.github.io/airtable-ruby/).
101
+
95
102
  ## Contributing
96
103
 
97
104
  1. Fork it ( https://github.com/aseroff/airtable-ruby/fork )
data/airtable.gemspec CHANGED
@@ -9,19 +9,17 @@ Gem::Specification.new do |spec|
9
9
  spec.version = Airtable::VERSION
10
10
  spec.authors = ['Andrew Seroff', 'Nathan Esquenazi', 'Alexander Sorokin']
11
11
  spec.email = ['andy@seroff.co']
12
- spec.summary = 'Easily connect to airtable data using ruby'
12
+ spec.summary = 'For when Airrecord is just too much.'
13
13
  spec.description = 'Easily connect to airtable data using ruby with access to all of the airtable features.'
14
14
  spec.homepage = 'https://github.com/aseroff/airtable-ruby'
15
15
  spec.license = 'MIT'
16
16
 
17
- spec.files = `git ls-files -z`.split("\x0")
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(docs|test)/}) }
18
18
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
19
  spec.require_paths = ['lib']
20
20
 
21
21
  spec.required_ruby_version = '>= 3.1'
22
- spec.add_dependency 'activesupport'
23
- spec.add_dependency 'httparty'
24
- spec.add_dependency 'json'
22
+ spec.add_dependency 'httparty', '>= 0.14.0'
25
23
 
26
24
  spec.add_development_dependency 'bundler'
27
25
  spec.add_development_dependency 'minitest'
@@ -30,7 +28,9 @@ Gem::Specification.new do |spec|
30
28
  spec.add_development_dependency 'rubocop-md'
31
29
  spec.add_development_dependency 'rubocop-minitest'
32
30
  spec.add_development_dependency 'rubocop-performance'
31
+ spec.add_development_dependency 'rubocop-rake'
33
32
  spec.add_development_dependency 'webmock'
34
- spec.add_development_dependency 'yard'
33
+
35
34
  spec.metadata['rubygems_mfa_required'] = 'true'
35
+ spec.metadata['github_repo'] = 'ssh://github.com/aseroff/airtable-ruby'
36
36
  end
data/lib/airtable/base.rb CHANGED
@@ -2,15 +2,15 @@
2
2
 
3
3
  # Object corresponding to an Airtable Base
4
4
  class Airtable::Base < Airtable::Resource
5
- def initialize(token, id)
6
- @token = token
5
+ def initialize(token, id, tables = nil)
6
+ super(token)
7
7
  @id = id
8
- self.class.headers({ 'Authorization': "Bearer #{@token}", 'Content-Type': 'application/json' })
8
+ @tables = tables
9
9
  end
10
10
 
11
- # Expects {name:,description:,fields:[]}
12
- # @see https://airtable.com/developers/web/api/create-table
11
+ # @param table_data [Hash] Payload for table creation. Expects {name:,description:,fields:[]}
13
12
  # @return [Airtable::Table]
13
+ # @see https://airtable.com/developers/web/api/create-table
14
14
  def create_table(table_data)
15
15
  response = self.class.post("#{base_url}/tables",
16
16
  body: table_data.to_json).parsed_response
@@ -20,17 +20,20 @@ class Airtable::Base < Airtable::Resource
20
20
  Airtable::Table.new @token, @id, response
21
21
  end
22
22
 
23
+ # @return [Array<Airtable::Table>]
23
24
  # @see https://airtable.com/developers/web/api/get-base-schema
24
- # @return [Array]<Airtable::Table>
25
25
  def tables
26
- response = self.class.get("#{base_url}/tables")
26
+ @tables ||= begin
27
+ response = self.class.get("#{base_url}/tables")
27
28
 
28
- check_and_raise_error(response)
29
+ check_and_raise_error(response)
29
30
 
30
- response['tables'].map { Airtable::Table.new(@token, @id, _1) }
31
+ response['tables'].map { Airtable::Table.new(@token, @id, _1['id'], _1) }
32
+ end
31
33
  end
32
34
 
33
35
  # Instantiate table in base
36
+ # @param table_id [String] ID of table
34
37
  # @return [Airtable::Table]
35
38
  def table(table_id)
36
39
  Airtable::Table.new(@token, @id, table_id)
@@ -38,6 +41,6 @@ class Airtable::Base < Airtable::Resource
38
41
 
39
42
  protected
40
43
 
41
- # Instantiate table in base
44
+ # Endpoint for bases
42
45
  def base_url = "/v0/meta/bases/#{@id}"
43
46
  end
@@ -2,13 +2,8 @@
2
2
 
3
3
  # Client carrying authorization token
4
4
  class Airtable::Client < Airtable::Resource
5
- def initialize(token)
6
- @token = token
7
- self.class.headers({ 'Authorization': "Bearer #{@token}", 'Content-Type': 'application/json' })
8
- end
9
-
5
+ # @return [Array<Airtable::Base>]
10
6
  # @see https://airtable.com/developers/web/api/list-bases
11
- # @return [Array]<Airtable::Base>
12
7
  def bases
13
8
  response = self.class.get('/v0/meta/bases').parsed_response
14
9
 
@@ -17,22 +12,22 @@ class Airtable::Client < Airtable::Resource
17
12
  response['bases'].map { Airtable::Base.new(@token, _1['id']) }
18
13
  end
19
14
 
20
- # @see https://airtable.com/developers/web/api/create-base
21
- # def create_base(base_data)
22
- # response = self.class.post('/v0/meta/bases'
23
- # body: base_data.to_json).parsed_response
24
- # check_and_raise_error(response)
25
- # Airtable::Base.new @token, response
26
- # 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
27
21
 
28
22
  # Instantiate base
23
+ # @param base_id [String] ID of base
29
24
  # @return [Airtable::Base]
30
25
  def base(base_id)
31
26
  Airtable::Base.new(@token, base_id)
32
27
  end
33
28
 
29
+ # @return [Hash] User's data based on token
34
30
  # @see https://airtable.com/developers/web/api/get-user-id-scopes
35
- # @return [Hash]
36
31
  def whoami
37
32
  response = self.class.get('/v0/meta/whoami').parsed_response
38
33
 
@@ -2,15 +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)
8
- @token = token
5
+ def initialize(token, base_id, table_id, id, data = nil)
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
- self.class.headers({ 'Authorization': "Bearer #{@token}", 'Content-Type': 'application/json' })
15
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}"
16
45
  end
@@ -4,46 +4,55 @@
4
4
  class Airtable::Table < Airtable::Resource
5
5
  attr_reader :name
6
6
 
7
- def initialize(token, base_id, api_response)
8
- @token = token
7
+ def initialize(token, base_id, id, data = nil)
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
13
- self.class.headers({ 'Authorization': "Bearer #{@token}", 'Content-Type': 'application/json' })
10
+ @id = id
11
+ @data = data
14
12
  end
15
13
 
16
- # @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
+
17
23
  # @return [Array<Airtable::Record>]
24
+ # @see https://airtable.com/developers/web/api/list-records
18
25
  def records
19
- response = self.class.get(table_url)
26
+ @records ||= begin
27
+ response = self.class.get(table_url)
20
28
 
21
- check_and_raise_error(response)
29
+ check_and_raise_error(response)
22
30
 
23
- 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
24
33
  end
25
34
 
26
35
  # Instantiate record in table
27
- # @return [Airtable::Table]
28
- def record(record_id)
29
- Airtable::Table.new(@token, @base_id, @id, record_id)
30
- 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)
31
39
 
32
- # @see https://airtable.com/developers/web/api/update-table
33
40
  # @return [Airtable::Table]
41
+ # @see https://airtable.com/developers/web/api/update-table
34
42
  def update(table_data)
35
43
  response = self.class.patch("/v0/meta/bases/#{@base_id}/tables/#{@id}",
36
44
  body: table_data.to_json).parsed_response
37
45
 
38
46
  check_and_raise_error(response)
39
47
 
40
- Airtable::Table.new @token, @base_id, response
48
+ Airtable::Table.new @token, @base_id, response['id'], response
41
49
  end
42
50
 
43
- # @note API maximum of 10 records at a time
44
- # @see https://airtable.com/developers/web/api/create-records
51
+ # @param [Array] Record objects to create
45
52
  # @return [Array<Airtable::Record>]
46
- 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)
47
56
  response = self.class.post(table_url,
48
57
  body: { records: Array(records).map { |fields| { fields: } } }.to_json).parsed_response
49
58
 
@@ -52,8 +61,10 @@ class Airtable::Table < Airtable::Resource
52
61
  response['records'].map { Airtable::Record.new(@token, @base_id, @id, _1) }
53
62
  end
54
63
 
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
@@ -73,5 +84,6 @@ class Airtable::Table < Airtable::Resource
73
84
 
74
85
  protected
75
86
 
87
+ # Endpoint for tables
76
88
  def table_url = "/v0/#{@base_id}/#{@id}"
77
89
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Version
4
4
  module Airtable
5
- VERSION = '0.2.1'
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.1
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Seroff
@@ -10,50 +10,22 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-10-26 00:00:00.000000000 Z
13
+ date: 2024-10-28 00:00:00.000000000 Z
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: activesupport
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: '0'
29
15
  - !ruby/object:Gem::Dependency
30
16
  name: httparty
31
17
  requirement: !ruby/object:Gem::Requirement
32
18
  requirements:
33
19
  - - ">="
34
20
  - !ruby/object:Gem::Version
35
- version: '0'
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: '0'
43
- - !ruby/object:Gem::Dependency
44
- name: json
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '0'
21
+ version: 0.14.0
50
22
  type: :runtime
51
23
  prerelease: false
52
24
  version_requirements: !ruby/object:Gem::Requirement
53
25
  requirements:
54
26
  - - ">="
55
27
  - !ruby/object:Gem::Version
56
- version: '0'
28
+ version: 0.14.0
57
29
  - !ruby/object:Gem::Dependency
58
30
  name: bundler
59
31
  requirement: !ruby/object:Gem::Requirement
@@ -153,7 +125,7 @@ dependencies:
153
125
  - !ruby/object:Gem::Version
154
126
  version: '0'
155
127
  - !ruby/object:Gem::Dependency
156
- name: webmock
128
+ name: rubocop-rake
157
129
  requirement: !ruby/object:Gem::Requirement
158
130
  requirements:
159
131
  - - ">="
@@ -167,7 +139,7 @@ dependencies:
167
139
  - !ruby/object:Gem::Version
168
140
  version: '0'
169
141
  - !ruby/object:Gem::Dependency
170
- name: yard
142
+ name: webmock
171
143
  requirement: !ruby/object:Gem::Requirement
172
144
  requirements:
173
145
  - - ">="
@@ -195,27 +167,6 @@ files:
195
167
  - README.md
196
168
  - Rakefile
197
169
  - airtable.gemspec
198
- - docs/Airtable.html
199
- - docs/Airtable/Base.html
200
- - docs/Airtable/Client.html
201
- - docs/Airtable/Error.html
202
- - docs/Airtable/Record.html
203
- - docs/Airtable/Resource.html
204
- - docs/Airtable/Table.html
205
- - docs/_index.html
206
- - docs/class_list.html
207
- - docs/css/common.css
208
- - docs/css/full_list.css
209
- - docs/css/style.css
210
- - docs/file.README.html
211
- - docs/file_list.html
212
- - docs/frames.html
213
- - docs/index.html
214
- - docs/js/app.js
215
- - docs/js/full_list.js
216
- - docs/js/jquery.js
217
- - docs/method_list.html
218
- - docs/top-level-namespace.html
219
170
  - lib/airtable.rb
220
171
  - lib/airtable/base.rb
221
172
  - lib/airtable/client.rb
@@ -224,14 +175,13 @@ files:
224
175
  - lib/airtable/resource.rb
225
176
  - lib/airtable/table.rb
226
177
  - lib/airtable/version.rb
227
- - test/airtable_test.rb
228
- - test/record_test.rb
229
- - test/test_helper.rb
178
+ - lib/airtable/workspace.rb
230
179
  homepage: https://github.com/aseroff/airtable-ruby
231
180
  licenses:
232
181
  - MIT
233
182
  metadata:
234
183
  rubygems_mfa_required: 'true'
184
+ github_repo: ssh://github.com/aseroff/airtable-ruby
235
185
  post_install_message:
236
186
  rdoc_options: []
237
187
  require_paths:
@@ -247,8 +197,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
247
197
  - !ruby/object:Gem::Version
248
198
  version: '0'
249
199
  requirements: []
250
- rubygems_version: 3.5.21
200
+ rubygems_version: 3.5.22
251
201
  signing_key:
252
202
  specification_version: 4
253
- summary: Easily connect to airtable data using ruby
203
+ summary: For when Airrecord is just too much.
254
204
  test_files: []