- Firestoreを操作するActiveRecord風のインタフェースをRailsアプリケーションに提供します。
- google-cloud-firestore gemのラッパーとして動作します。
このgemを使う前に、以下の点に注意してください。
- このgemはあくまでActiveRecord風のAPIを提供しているだけであり、ActiveRecordと完全な互換性があるわけではありません。そのため、ActiveStorageやDevise、Kaminari、Ransackなど、ActiveRecordの使用を前提としたgemやフレームワークをFirestoreに置き換えることはできません。
- FirestoreはいわゆるNoSQLであるため、RDBMSとは根本的に異なるデータ設計を考える必要があります。このgemを使ってActiveRecord風のAPIを手に入れたとしても、根本的なデータ設計についてはNoSQLのベストプラクティスに従う必要があります。
Add this line to your application's Gemfile:
gem "act_as_fire_record_beta"
And then execute:
$ bundle
Or install it yourself as:
$ gem install act_as_fire_record_beta
- Firebase Emulatorをインストールします。
firebase init
でプロジェクト用のFirestoreをセットアップします。- このWikiページを参考にして
.gitignore
の設定を追加します。 - 環境変数
FIRESTORE_EMULATOR_HOST
にEmulatorのhost情報を設定します。(export FIRESTORE_EMULATOR_HOST=127.0.0.1:8080
など) firebase emulator:start
でEmulatorを起動し、それからRailsを起動します。firebase emulators:start --import=./firebase-local --export-on-exit
のように--import
オプションと--export-on-exit
オプションを付けると、作成したデータをローカルに保存できます。- データを保存するディレクトリは
.gitignore
に追加しておきましょう。
firebase emulators:exec 'bundle exec rspec' --only firestore
のようなコマンドを入力すると、Emulatorの起動、テストの実行、Emulatorの終了が一度に行えます。
- Firebaseプロジェクトを作成し、 プロジェクト内にFirestoreを追加します。
- 「https://console.cloud.google.com/ > 左サイドメニュー > APIとサービス > 認証情報 > サービスアカウント > 名前=App Engine default service account のアカウントの鉛筆マークをクリック > キータブ > 鍵を追加 > 新しい鍵を作成 > JSON形式」でCredentialをダウンロードします。
- CredentialをRailsプロジェクト内の任意のディレクトリに配置します。
- CredentialがGitHubにpushされないよう、必ず
.gitignore
にCredentialのパスを追加してください。
- CredentialがGitHubにpushされないよう、必ず
- (ローカルで実行する場合)環境変数
GOOGLE_APPLICATION_CREDENTIALS
にCredentialへのパスを追加します。(export GOOGLE_APPLICATION_CREDENTIALS=path/to/your-key.json
など) - (サーバーで実行する場合)環境変数
FIRESTORE_CREDENTIALS
にCredentialの内容(JSON文字列)を書き込みます。 config/initializers/firestore.rb
にproject_id
を設定します。
require "google/cloud/firestore"
Google::Cloud::Firestore.configure do |config|
config.project_id = "your-awesome-project"
end
- 作成したデータ(ドキュメント)は「(モデル名)-(実行環境)」という名前のコレクションに保存されます(例:
books-development
、blog_comments-production
)
モデルの設定例です。
class Book
include ActAsFireRecordBeta
firestore_attribute :title, :string
firestore_attribute :published_on, :date
firestore_attribute :page, :integer
validates :title, presence: true
before_validation :titleize_title
private
def titleize_title
self.title = title.to_s.titleize
end
end
- クラスはPORO(Plain Old Ruby Object)として定義します。
ApplicationRecord
は継承しないでください。
ActAsFireRecordBeta
をincludeします。- Firestoreで管理したい属性と型を
firestore_attribute
で指定します。- このメソッドに指定可能な引数は
ActiveModel::Attributes::ClassMethods#attribute
と同じです。
- このメソッドに指定可能な引数は
- (オプション)必要に応じてバリデーションを追加します。
- バリデーションには
ActiveModel::Validations::ClassMethods
が使われます。
- バリデーションには
- (オプション)必要に応じてバリデーションコールバックを追加します。
- コールバックには
ActiveModel::Validations::Callbacks::ClassMethods
が使われます。
- コールバックには
belongs_to
やhas_many
のようなモデルの関連は使えません。
単純なCRUDの例です。
# Create
book = Book.new(title: 'An Awesome Book', published_on: '2022-12-01'.to_date, page: 200)
book.save
book.id #=> IdG0ZWT0I5DucEQuRgoP
# Read
id = 'IdG0ZWT0I5DucEQuRgoP'
book = Book.find(id)
# Update
book.update(page: 210)
# Delete
book.destroy
検索メソッドの使用例です。
book = Book.find_by(title: 'An Awesome Book')
books = Book.all
books = Book.order(:title)
books = Book.order(:title, :desc)
books = Book.where(:page, :>=, 200)
books = Book.where(:page, :>=, 200).order(:page)
上記以外のAPIの使用例はテストコードを参照してください。
- https://github.com/JunichiIto/act_as_fire_record_beta/blob/main/test/act_as_fire_record_beta_test.rb
- https://github.com/JunichiIto/act_as_fire_record_beta/blob/main/test/google/cloud/firestore/query_test.rb
order
メソッドやwhere
メソッドはGoogle::Cloud::Firestore::Query
をそのまま使っているため、引数の指定方法がActiveRecordと異なります。- 指定可能な検索条件には制約があります。具体的にはFirestoreやgoogle-cloud-firestoreの制約がそのまま当てはまります。
RDBMSを使ったテストとは異なり、テストで使用したデータは自動的に削除されません。必要に応じて不要なデータを削除してください。
require "test_helper"
class ActAsFireRecordBetaTest < ActiveSupport::TestCase
setup do
Book.destroy_all
end
test "create" do
Book.create(title: 'An Awesome Book', published_on: '2022-12-01'.to_date, page: 200)
assert_equal 1, Book.count
end
end
require "rails_helper"
RSpec.describe Book, type: :model do
before do
Book.destroy_all
end
it "creates new record" do
Book.create(title: 'An Awesome Book', published_on: '2022-12-01'.to_date, page: 200)
expect(Book.count).to eq 1
end
end
GitHub Actions上でFirebase Emulatorを使用する設定例をこちらのWikiページに載せています。
Issuesをご覧ください。
Contribution directions go here.
The gem is available as open source under the terms of the MIT License.