Railsもいよいよバージョン8に!ということでリリース記事から抜き出した、 以下の特徴を実際に検証してみました。
個人的にはSQLiteがproductionでも使っていいよ、となったのが嬉しい部分かも。 なんとなく敷居の高かったActionCableも一段と使いやすくなってるはず?7.2での実装例を参考にしながら、ちょっと試してみます。
まずは普通にscaffoldとchannelを作ります。
rails new myapp
cd myapp
rails g scaffold message body
rails db:create db:migrate
rails g channel notification
以前はここで、cable.ymlを弄ってadapterの設定をしていましたが、デフォルトのasync
のまま進みます。
app/channels/notification_channel.rb
を開いて、stream_fromを以下のように書き換えます。
stream_from "notification_channel"
今回はレコードが作成、更新、削除される度に更新を通知したいと思います。app/controllers/rooms_controller.rb
の create
update
destroy
アクション内に以下の行を追加します。
ActionCable.server.broadcast "notification_channel", {content: @message}
通知を受け取った際に行いたい処理を app/javascript/channels/notification_channel.js
の received メソッド内に記述します。
パフォーマンスの観点からは、更新が必要な箇所だけ書き換える方が望ましいですが、ページ全体をリロードしちゃってます。
if (location.pathname == "/messages"){
location.reload();
}
準備はこれだけです。 一つ目のタブで メッセージの一覧 (/messages) を開いておいて、別のタブで新規作成フォーム(/messages/new)を開いて何か入力してみると、最初のウィンドウに更新内容が(ページをリロードしなくても)表示されるはずです!
さて、これを実際にVPSサーバなどに配備して公開するとどうなるんでしょう?プロジェクト一式をサーバに転送して以下の手順で立ち上げてみました。注意点としては、productionのデータベースもstorage
フォルダに作成されるので、ここを永続化しておかないと(=例えばcapistranoやherokuみたいなアプリを全部置き換えるようなデプロイ方法を採用してると)バージョンアップの度にデータが全部消えてしまいます。
rm -r storage && ln -s ../storage # ここは環境によって全然違うので参考程度に
export RAILS_ENV=production
bundle install
rails db:setup
rails assets:precompile
小規模なシステムなら、時々 storage にスナップショット(ダンプファイルとか)でも置いておけば一箇所で管理できるので便利そうです(ActiveStorageのリソースもここに置く場合)。
これでバッチリ!かと思いきやRailsとは関係ない制約に引っかかって残念ながら公開できるデモは作れませんでした😅
時間ができたらPumaを単体で動かして公開してみようかなと思います。
続いて、認証機能の作成支援も試してみます(Devise卒業できるのか?)。
rails g authentication
connection.rbでコンフリクトを起こしますが、上書きして進みます。
データベースのマイグレーションファイル(yymmdd_create_users.rb
)を編集して、ユーザに持たせたい情報を追加します。
以下は名前を格納する列を定義する例です。
t.string :name, null: false, default: ''
編集が終わったらテーブルを作成します。
rails db:migrate
サンプルのユーザも作成します。これはrails c
で起動したコンソール上で実行してください。
User.create(email_address: "test@lmlab.net", password: "secret")
デフォルトでは認証完了後にトップページ(rootで定義されたパス)にリダイレクトするので、config/routes.rb
に以下の設定を追加します。
root "messages#index"
代わりに app/controllers/concertns/authentication.rb
の中の after_authentication_url
を編集して任意のページに遷移させることも可能です。
ビューの中では以下のようにログイン状態や現在のユーザ情報などを取得することが可能です(authentication.rb
に記述あり)。
<% if authenticated? %>
<p>Signed in as <%= Current.session.user.email_address %>
<%= button_to "Sign out", session_path, method: :delete %>
</p>
<% end %>
認証が必要ないアクションは以下ようにコントローラに宣言することが可能です(skip_before_action :require_authentication
でも多分OK)。
allow_unauthenticated_access only: %i[ index show ]
Sprocketsに変わってデフォルトになったらしいpropshaft。誤解をおそれずざっくりまとめると、新しいHTTPプロトコルとかフロント側(JavaScript)の管理ツールが充実してきたので、必要最低限のリソース管理に立ち戻った、という感じでしょうか。
digestの付与がちょっとスッキリしていて良い感じ。
<%= image_tag 'Ruby_logo.png' %>
↓
<img src="/assets/Ruby_logo-69c59d4c.png" />
SCSSとか入れなくても、普通のCSS内のリソースもよしなに扱ってくれてる様子です。これは助かる…!
background-image: url("Ruby_logo.png");
↓
background-image: url("/assets/Ruby_logo-69c59d4c.png");