[Rails] Action Cableの実装方法

JQueryは古いテクノロジーとはいえ、さくっと動くものを作るときは異常に簡単です。 古いテクノロジーは悪ではなく適材適所で使っていくのが大事だと思っています。

まずは、最初からあるapp/assets/javascripts/cable.jsを該当layoutで読み込みます。

# app/assets/javascripts/application.js
...
//= require cable.js

全部のViewでApp.cableを呼ぶ必要はないのでcontent_forでActionCableとの通信をとるViewだけJSを走らせるようにします。

#app/views/layouts/application.html.erb
<head>
 ...
 <%= yield :page_scripts %>
</head>

JSでは、App.cableにイベントを登録していきます。 引数のchannelにはクラス名、引数を渡すとparamsに入ってサーバ側で処理できます。this.performを使ってクラス内のメソッドを呼ぶことができます。development環境では別プロセスで動作確認ができないのでsetTimeoutを用いてテストしています。

<% content_for :page_scripts do %>
<script>
  $(function(){    
    // Subscrubung host status 
    $('span.host-status')
    .filter(function(i){
      return $(this).text() !== "terminated";
    })
    .each(function(i){
      var hostId = $(this).data('hostId');
      var self = this;
      App.cable.subscriptions.create({channel: "HostStatusChannel", host_id: hostId}, {
        connected: function(){                                                          
          console.log('connected');
          //var self = this;                                                            
          //setTimeout(function(){                                                      
          //  console.log('say now');                                                   
          //  self.perform("say");                                                      
          //}, 1000);                                                                   
        },                                                                            
        received: function (data) {                                                   
          var currentStatus = $(self).text();
          if(data.status !== currentStatus){
            $(self).fadeOut(500, function(){
              $(self).text(data.status);
              $(self).fadeIn();
            });
          }
        },                                                                            
      });                                                                             
    });
  }); 
</script>
<% end %>

HTML部分は下記のような感じ。

<span class="host-status" data-host-id="<%= host.id %>"><%= host.status %></span>

で最後になりますが、ActionCableを継承したクラスです。subscribedがconnectionとともに走ります。 stream_for MODELでモデルに関係したチャネルが接続されます。 そして、broadcast_to(MODEL, object)でそのモデルへの接続を確率したチャネルにプッシュすることができます。

# app/channels/host_status_channel.rb
class HostStatusChannel < ApplicationCable::Channel
  def subscribed
    host = Host.find(params[:host_id])
    stream_for host 
  end
   def say # for testing
    HostStatusChannel.broadcast_to(Host.find(1), "hi")
  end
 end

これでダイナミックにDOMを操作できるようになりました。

[Rails] Device利用時のconnection.rb(Action Cable)

Railsガイドで説明されているconnection.rbはcookieを利用しているもので、deviseを利用する場合は、request.envに設定されているwardenのものを取ってくる必要がある。 もしくはsessionの中を漁る感じ、request.envの方が綺麗に書けるのでこちらを採用した。 (Essentially, the both are cookie tho..)

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user
 
    def connect
      self.current_user = find_verified_user
    end
 
    private
      def find_verified_user
        if verified_user = request.env['warden'].user 
          verified_user
        else
          reject_unauthorized_connection
        end
      end
  end
end

参考: https://stackoverflow.com/questions/38470463/rails-devise-action-cable

[ChromeOS] Crostiniで日本語入力する

ここ何年もLinuxに触ってなかったので久しぶりに日本語入力系の話。昔は、Cannaとか使ってましたね。SKK/Anthyで院生のときは過ごしてたと思います。

Crostiniでも日本語入力を扱いたいのでGoogleの日本語入力のMozc(モズク)を初インストール。

$ sudo apt-get install fcitx-mozc

fcitxというのも初めて。apt-getでプロセスが上がってくる(確か)

$ ps -ef | grep fci
shohei.+   264    88  0 08:13 ?        00:00:03 fcitx
shohei.+   280    88  0 08:13 ?        00:00:01 /usr/bin/dbus-daemon --fork --print-pid 5 --print-address 7 --config-file /usr/share/fcitx/dbus/daemon.conf
shohei.+   284    88  0 08:13 ?        00:00:00 /usr/bin/fcitx-dbus-watcher unix:abstract=/tmp/dbus-jYqdpnGPBg,guid=2870007bcc26b2aa1f1477c15ba186aa 280
shohei.+  1562   621  4 08:32 pts/2    00:00:06 fcitx-config-gtk3
shohei.+  1661  1593  0 08:34 pts/4    00:00:00 grep fci

XMODIFIERSを設定しろと言われたので下記のコマンドで環境変数を設定する。

$ export XMODIFIERS=@im=fcitx

fcitx-configtoolでGUIから設定できる。

$ fcitx-configtool

inputメソッドにmozcを追加。

英語キーボードなのでLayoutを指定。

firefoxか何かをあげてctrl+spaceで入力が表示される。

[ChromeOS] Crostini VMの再起動方法

crostiniのXがよく落ちるのでCrostini VMを再起動するケースがよくある。手順は簡単で、

  1. croshを起動
  2. vmc stop termina
  3. vms start termina
crosh> vmc list
termina
Total Size (bytes): 4176281600
crosh> vmc stop termina
crosh> vmc start termina