Keep your Ruby on Rails records in sync with AirTable.
Currently only one way Rails => AirTable synchronization.
For the latest changes, see the CHANGELOG.md.
Add this line to your application's Gemfile:
gem 'airtable_sync'
And then execute:
$ bundle
Then run the install generator:
bundle exec rails generate airtable_sync:install
In config/initializers/airtable_sync.rb
you can specify configuration options:
api_key
- In order to use this gem, you need to generate AirTable API key: https://airtable.com/create/apikeyairtable_base_id
- you can setairtable_base_id
here or overridedef airtable_base_id
in your model. More on this below.skip_airtable_sync
- if set totrue
, AirtableSync will not sync records to AirTable. This is useful for development and test environments where you don't want to sync records to AirTable.
Example:
AirtableSync.configure do |config|
config.api_key = ENV.fetch('AIRTABLE_API_KEY')
config.skip_airtable_sync = ActiveModel::Type::Boolean.new.cast(ENV.fetch('SKIP_AIRTABLE_SYNC'))
end
You need to create the AirTable base(s) and table(s) yourself.
For each model that you want to sync to AirTable, you need to run the connection generator:
bundle exec rails generate airtable_sync:connection Article
Please note that this does not create the AirTable table. You need to already have it or create it manually.
There are couple of ways how you can set the airtable_base_id
to be used.
In config/initializers/airtable_sync.rb
you can specify airtable_base_id
:
AirtableSync.configure do |config|
config.airtable_base_id = ENV.fetch('AIRTABLE_BASE_ID')
end
# app/models/article.rb
class Article < ApplicationRecord
include AirtableSync::RecordSync
def airtable_base_id
site.airtable_base_id
end
end
By default, AirtableSync calls #as_airtable_json
on a record to get the fields that it needs to push to AirTable. #as_airtable_json
simply calls #as_json
in its default implementation. To change this behavior, you can override #as_airtable_json
in your model:
# app/models/article.rb
class Article < ApplicationRecord
include AirtableSync::RecordSync
def as_airtable_json
{
'Post Title': self.title.capitalize,
'Short Description': self.title.parameterize,
'Long Description': self.created_at,
}
end
end
If AirTable table name does not match the Rails model collection name, you need to specify table name for each CreateRecordJob
, DestroyRecordJob
, and UpdateRecordJob
call. If not specified, model collection name is used as the table name.
You also need to replace included AirtableSync::RecordSync
with custom callbacks that will call appropriate AirtableSync jobs.
For example:
AirtableSync::CreateRecordJob.perform_later(model_name, id, table_name)
AirtableSync::UpdateRecordJob.perform_later(model_name, id, table_name)
AirtableSync::DestroyRecordJob.perform_later(table_name:, airtable_id:)
Where:
model_name
- Rails model withairtable_id
columntable_name
- AirTable table name (defaults to:model_name.underscore.pluralize.humanize
)
For example:
AirtableSync::CreateRecordJob.perform_now('articles', 1, 'Stories')
Or, if you want to use the default 'Articles' table name:
AirtableSync::CreateRecordJob.perform_now('articles', 1) # table_name defaults to 'Articles'
After setting up which models you want to sync to AirTable, you can run the initial sync for each of the models:
AirtableSync::InitialSyncJob.perform_later('articles')
You can also run this from a Rake task:
bundle exec rails "airtable_sync:initial_sync[articles]"
Quotes are needed in order for this to work in all shells.
This gem silently "fails" (does nothing) when airtable_base_id
or airtable_id
is nil
! This is not always desired behavior so be aware of that.
PRs welcome!
To run RuboCop style check and RSpec tests run:
bundle exec rake
To run only RuboCop run:
bundle exec rails style
To run RSpec tests run:
bundle exec spec
The gem is available as open source under the terms of the MIT License.