ルールを破る:SQLiteを使用してWebアプリをデモする
公開: 2022-03-10ほとんどの潜在的なユーザーは、時間とお金を費やす前に、ソフトウェアまたはサービスを試してみたいと思うでしょう。 一部の製品は、ユーザーに無料トライアルを提供するだけでうまく機能しますが、他のアプリは、サンプルデータがすでに用意されている状態で最もよく体験できます。 多くの場合、これは古くからのデモアカウントが機能する場所です。
ただし、デモアカウントを実装したことがある人なら誰でも、関連する問題を証明できます。 インターネット上で物事がどのように実行されるかを知っています。誰でもデータを入力でき(製品にとって意味があるかどうかに関係なく)、匿名ユーザーまたはボットによって追加されたコンテンツが他の人に不快感を与える可能性があります。 もちろん、いつでもデータベースをリセットできますが、どのくらいの頻度でいつですか? そして最終的に、それは本当に問題を解決しますか? SQLiteを使用するための私のソリューション。
プロダクションバージョンにSQLiteを使用してみませんか?
SQLiteは、書き込みコマンド中にデータベース全体がロックされるため、複数のスレッドを処理しないことが一般的に知られています。これが、通常の実稼働環境でSQLiteを使用しない理由の1つです。 ただし、私のソリューションでは、ソフトウェアをデモするユーザーごとに個別のSQLiteファイルが使用されます。 つまり、書き込みの制限はその1人のユーザーにのみ制限されますが、複数の同時ユーザー(それぞれが独自のデータベースファイルを持つ)ではこの制限は発生しません。 これにより、ユーザーがソフトウェアを試運転するための制御されたエクスペリエンスが可能になり、ユーザーが見たいものを正確に表示できるようになります。
このチュートリアルは、2015年からSaaSデモWebアプリで正常に実行されている実際のソリューションに基づいています。チュートリアルはRuby on Rails(私の選択したフレームワーク)バージョン3以降用に作成されていますが、基本的な概念は次のとおりです。他の言語やフレームワークに適応させることができます。 実際、Ruby on Railsはソフトウェアパラダイム「設定より規約」に従っているため、他のフレームワーク、特にベア言語(ストレートPHPなど)やデータベース接続の管理に関してあまり機能しないフレームワークでの実装がさらに簡単になる場合があります。 。
そうは言っても、この手法はRuby onRailsに特に適しています。 なんで? なぜなら、ほとんどの場合、それは「データベースにとらわれない」からです。 つまり、Rubyコードを記述し、データベースを問題なく切り替えることができるはずです。
このプロセスの完成版のサンプルは、GitHubからダウンロードできます。
最初のステップ:展開環境
後でデプロイしますが、Ruby on Railsはデフォルトで開発、テスト、本番環境に分割されています。 このリストに、本番環境とほぼ同じであるが、異なるデータベース設定を使用できるようにする、アプリの新しいデモ環境を追加します。
Railsで、 config/environments/production.rb
Production.rbファイルを複製して新しい環境を作成し、名前をdemo.rb
に変更します。 デモ環境は本番環境のような設定で使用されるため、この新しい環境の多くの構成オプションを変更する必要はありませんが、 config.assets.compile
をfalse
からtrue
に変更することをお勧めします。これにより、ローカルでのテストが簡単になります。プリコンパイルする必要があります。
Rails 4以降を実行している場合は、 config/secrets.yml
を更新して、デモ環境用のsecret_key_base
を追加する必要もあります。 この秘密鍵を本番環境とは異なるものにして、各環境間でセッションが一意になるようにし、アプリをさらに保護してください。
次に、 config/database.yml
でデータベース構成を定義する必要があります。 デモ環境では、主に次のセクションで説明する複製データベースを使用しますが、デモに使用するデフォルトのデータベースファイルと設定を定義する必要があります。 以下をconfig/database.yml
に追加します。
demo: adapter: sqlite3 pool: 5 timeout: 5000 database: db/demo.sqlite3
Railsでは、 Gemfile
をチェックして、SQLite3が新しいデモ環境で使用可能であることを確認することもできます。 これはさまざまな方法で設定できますが、次のようになります。
group :development, :test, :demo do gem 'sqlite3' end
データベースを構成したら、 rake db:migrate RAILS_ENV=demo
してから、必要に応じてデータベースにデータをシードする必要があります(シードファイルからのものか、新しいデータを手動で入力するか、 development.sqlite3
ファイルを複製するかどうか)。 この時点で、コマンドラインからrails server -e demo
を実行して、すべてが機能していることを確認する必要があります。 新しいデモ環境でサーバーを実行しているときに、テストデータが希望どおりであることを確認できますが、後でいつでも戻ってそのコンテンツを編集できます。 コンテンツをデモデータベースに追加するときは、ファイルができるだけ小さくなるように、クリーンなデータセットを作成することをお勧めします。 ただし、別のデータベースからデータを移行する必要がある場合は、データのダンプと復元のためにデータベースに依存しない形式を作成するYamlDbをお勧めします。
Railsアプリケーションが期待どおりに実行されている場合は、次の手順に進むことができます。
2番目のステップ:デモデータベースの使用
このチュートリアルの重要な部分は、各セッションで異なるSQLiteデータベースファイルを使用できるようにすることです。 通常、アプリケーションはすべてのユーザーの同じデータベースに接続するため、このタスクには追加のコードが必要になります。
Ruby on Railsでデータベースを切り替えることができるようにするには、まず次の4つのプライベートメソッドをapplication_controller.rb
に追加する必要があります。 また、メソッドset_demo_database
のbeforeフィルターを定義して、ページが読み込まれるたびに正しいデモデータベースを参照するロジックが呼び出されるようにする必要があります。
# app/controllers/application_controller.rb # use `before_filter` for Rails 3 before_action :set_demo_database, if: -> { Rails.env == 'demo' } private # sets the database for the demo environment def set_demo_database if session[:demo_db] # Use database set by demos_controller db_name = session[:demo_db] else # Use default 'demo' database db_name = default_demo_database end ActiveRecord::Base.establish_connection(demo_connection(db_name)) end # Returns the current database configuration hash def default_connection_config @default_config ||= ActiveRecord::Base.connection.instance_variable_get("@config").dup end # Returns the connection hash but with database name changed # The argument should be a path def demo_connection(db_path) default_connection_config.dup.update(database: db_path) end # Returns the default demo database path defined in config/database.yml def default_demo_database return YAML.load_file("#{Rails.root.to_s}/config/database.yml")['demo']['database'] end
サーバーセッションごとに異なるデータベースがあるため、データベースのファイル名をセッション変数に格納します。 ご覧のとおり、 session[:demo_db]
を使用して、ユーザーの特定のデータベースを追跡しています。 set_demo_database
メソッドは、セッション変数に設定されたデータベースへの接続を確立することにより、使用するデータベースを制御します。 default_demo_database
メソッドは、 database.yml
構成ファイルで定義されているデータベースのパスをロードするだけです。
ギナオ語を使用している場合は、この時点で、データベース接続スクリプトを更新して新しいデータベースを指すようにしてから、次のセクションに進むことができます。 Railsでは、「設定より規約」のソフトウェアパラダイムに従っているため、さらにいくつかの手順が必要です。
3番目のステップ:SQLiteファイルの複製
アプリが新しいデータベースを使用するように設定されたので、新しいデモセッションのトリガーが必要です。 簡単にするために、基本的な「デモの開始」ボタンを使用することから始めます。 また、名前やメールアドレス(営業チームからのフォローアップなど)など、さまざまなものを収集するフォームにすることもできます。
Railsの規則に従い、新しい「デモ」コントローラーを作成します。
rails generate controller demos new
次に、新しいコントローラーアクションを指すようにルートを更新し、それらを条件付きでラップして、実稼働環境で呼び出されないようにする必要があります。 ルートには任意の名前を付けるか、標準のRails規則を使用して名前を付けることができます。
if Rails.env == 'demo' get 'demos/new', as: 'new_demo' post 'demos' => 'demos#create', as: 'demos' end
次に、 views/demos/new.html.erb
に非常に基本的なフォームを追加しましょう。 キャプチャするフォームフィールドを追加することをお勧めします。
<h1>Start a Demo</h1> <%= form_tag demos_path, method: :post do %> <%= submit_tag 'Start Demo' %> <% end %>
魔法はcreate
アクションで発生します。 ユーザーがこのルートに送信すると、アクションは新しい一意のファイル名でdemo.sqlite3
ファイルをコピーし、セッション変数を設定し、ユーザーにログインして(該当する場合)、ユーザーを適切なページにリダイレクトします(これを'ダッシュボード')。
class DemosController < ApplicationController def new # Optional: setting session[:demo_db] to nil will reset the demo session[:demo_db] = nil end def create # make db/demos dir if doesn't exist unless File.directory?('db/demos/') FileUtils.mkdir('db/demos/') end # copy master 'demo' database master_db = default_demo_database demo_db = "db/demos/demo-#{Time.now.to_i}.sqlite3" FileUtils::cp master_db, demo_db # set session for new db session[:demo_db] = demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) # Redirect to wherever you want to send the user next redirect_to dashboard_path end end
これで、running rails server -e demo
を使用してサーバーをもう一度起動することにより、デモコードをローカルで試すことができるはずです。
サーバーがすでに実行されている場合は、本番サーバーのようにコードをキャッシュするように構成されているため、変更を加える場合はサーバーを再起動する必要があります。
すべてのコードが期待どおりに機能したら、バージョン管理に変更をコミットし、 db/demos
ディレクトリ内のファイルではなく、 demo.sqlite3
ファイルをコミットするようにしてください。 gitを使用している場合は、 .gitignore
ファイルに次を追加するだけです。
デモユーザーから追加情報(名前や電子メールなど)を収集する場合は、デモデータベースの信頼性が低いため、APIを介してメインアプリケーションまたはその他の販売パイプラインにその情報を送信することをお勧めします。 (再デプロイするたびにリセットされます)。
!/db/demo.sqlite3 db/demos/*
最終ステップ:デモサーバーのデプロイ
デモのセットアップがローカルで機能するようになったので、誰もが使用できるように、明らかにそれをデプロイする必要があります。 アプリはそれぞれ異なりますが、デモアプリは別のサーバーに配置することをお勧めします。したがって、本番アプリ(demo.myapp.comなど)としてドメインを使用することをお勧めします。 これにより、2つの環境を確実に分離できます。 さらに、SQLiteファイルはサーバーに保存されているため、Herokuなどのサービスはファイルシステムへのアクセスを提供しないため機能しません。 ただし、実質的にすべてのVPSプロバイダー(AWS EC2、Microsoft Azureなど)を引き続き使用できます。 自動化された便利さが気に入った場合は、VPSでの作業を可能にするサービスとしての他のプラットフォームオプションがあります。
展開プロセスに関係なく、デモSQLiteファイルを保存するディレクトリに対してアプリに適切な読み取り/書き込み権限があることを確認する必要がある場合もあります。 これは、手動またはデプロイメントフックを使用して処理できます。
SQLiteは私のために動作しません。 他のデータベースシステムはどうですか?
2つのアプリが同じように作成されることはなく、データベースの要件もありません。 SQLiteを使用すると、データベースをすばやく複製できるだけでなく、ファイルをバージョン管理に保存できるという利点があります。 SQLiteはほとんどの状況(特にRailsで)で機能すると思いますが、SQLiteがアプリケーションのニーズに適していない場合もあります。 幸いなことに、他のデータベースシステムでも上記と同じ概念を使用することは可能です。 データベースを複製するプロセスはシステムごとに少し異なりますが、MySQLのソリューションの概要を説明し、PostgreSQLなどにも同様のプロセスが存在します。
上記の方法の大部分は、追加の変更なしで機能します。 ただし、SQLiteファイルをバージョン管理に保存する代わりに、 mysqldump
(またはPostgreSQLの場合はpg_dump
)を使用して、デモエクスペリエンスに使用するコンテンツが含まれているデータベースのSQLファイルをエクスポートする必要があります。 このファイルは、バージョン管理にも保存する必要があります。
前のコードへの唯一の変更は、 demos#create
アクションにあります。 SQLite3ファイルをコピーする代わりに、コントローラーアクションは新しいデータベースを作成し、そのデータベースにSQLファイルをロードし、必要に応じてデータベースユーザーにアクセス許可を付与します。 アクセスを許可する3番目のステップは、データベース管理者ユーザーがアプリが接続に使用するユーザーと異なる場合にのみ必要です。 次のコードは、標準のMySQLコマンドを使用してこれらの手順を処理します。
def create # database names template_demo_db = default_demo_database new_demo_db = "demo_database_#{Time.now.to_i}" # Create database using admin credentials # In this example the database is on the same server so passing a host argument is not require `mysqladmin -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } create #{new_demo_db}` # Load template sql into new database # Update the path if it differs from where you saved the demo_template.sql file `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } #{new_demo_db} < db/demo_template.sql` # Grant access to App user (if applicable) `mysql -u#{ ENV['DB_ADMIN'] } -p#{ ENV['DB_ADMIN_PASSWORD'] } -e "GRANT ALL on #{new_demo_db}.* TO '#{ ENV['DB_USERNAME'] }'@'%';"` # set session for new db session[:demo_db] = new_demo_db # Optional: login code (if applicable) # add your own login code or method here login(User.first) redirect_to dashboard_path end
Rubyを使用すると、PHPを含む他の多くの言語と同様に、バッククォートを使用して、コード内からシェルコマンド(つまり、 `ls -a`
)を実行できます。 ただし、これは注意して使用し、悪意を持って挿入されたコードからサーバーを保護するために、ユーザー向けのパラメーターや変数をコマンドに挿入できないようにする必要があります。 この例では、MySQLコマンドラインツールを明示的に操作しています。これは、新しいデータベースを作成する唯一の方法です。 これは、Ruby onRailsフレームワークが新しいデータベースを作成するのと同じ方法です。 ENV['DB_ADMIN']
およびENV['DB_ADMIN_PASSWORD']
は、必ず独自の環境変数またはデータベースのユーザー名を設定するその他の方法に置き換えてください。 管理者ユーザーがアプリのユーザーと異なる場合は、 ENV['DB_USERNAME']
に対して同じことを行う必要があります。
MySQLに切り替えるのに必要なのはこれだけです! このソリューションの最も明らかな利点は、データベースシステム間の構文の違いから生じる可能性のある潜在的な問題について心配する必要がないことです。
最終的には、利便性やスピードではなく、期待される品質やサービスに基づいて最終決定が下され、必ずしも価格だけに影響されるわけではありません。
最終的な考え
これは、新しいデモサーバーでできることの出発点にすぎません。 たとえば、マーケティングWebサイトに「機能XYZを試す」へのリンクを含めることができます。 名前やメールアドレスが必要ない場合は、 demos#create
メソッドを/demos/?feature=xyz
などのリンクにリンクすると、アクションは、のダッシュボードではなく、目的の機能やページにリダイレクトされます。上記の例。
また、開発環境とデモ環境にSQLiteを使用する場合、このサンプルデータベースを常にバージョン管理に含めると、すべての開発者がローカル開発、テスト環境、または品質保証テストで使用するクリーンなデータベースにアクセスできるようになります。 可能性は無限大。
完成したデモはGitHubからダウンロードできます。