【RouletteTalk】トークテーマをコピーして新しくルーレットを作成できる機能を追加しました

RouletteTalkに既存のルーレットのトークテーマをのみコピーして新規作成できる機能を追加しました。 RouletteTalkについては以下をご確認ください。

  • RouletteTalk

roulette-talk.com

  • リリースブログ

siso255.hatenablog.com

概要

画面下部にある「トークテーマをコピーして新規作成」をクリックすることで、表示しているルーレットのトークテーマをコピーして新しくルーレットを作成できます。複数テーブルに分かれてのイベントで、主催者が設定したトークテーマを各テーブルで使ってほしい場合などにお使いいただけます。

使い方

  1. コピー元のルーレットにトークテーマを設定します。
    ※既にトークテーマが設定されている場合はこちらの手順をスキップしてください。
  2. トークテーマをコピーして新規作成」をクリックします。
  3. 新規作成に成功すると画面上部にメッセージが表示されます。
    話す人は0件で新規作成されますので、「話す人」を追加してルーレットをお使いください。

トークテーマのルーレットを作成できるサービス「RouletteTalk」をリリースしました

はじめに

オンライン飲み会で使える、トークテーマのルーレットを作れるサービス「RouletteTalk」をリリースしました。

  • RouletteTalkのURL

roulette-talk.com

github.com

自己紹介

オンラインスクール「フィヨルドブートキャンプ」で学習をしているsiso255と申します。現在はSIerプログラマーとして働いています。

RouletteTalkとは

概要

トークテーマと話す人を設定したルーレットを作れるWebサービスです。作成したルーレットは自動的に保存されます。

使い方

  1. 「ルーレットを作る」をクリックします。
  2. 画面右側のトークテーマと話す人を設定します。「+トークテーマを追加する」をクリックすることでトークテーマを追加、既存のトークテーマをクリックすることで編集ができます。トークテーマにカーソルを合わせた際に表示される「×」ボタンをクリックすることでトークテーマを削除できます。話す人についてもトークテーマと同様の手順で設定します。

    トークテーマ、話す人の一覧
    「+トークテーマを追加する」をクリック時
    トークテーマ編集時
    トークテーマ削除ボタン

  3. 画面左側の「スタート」ボタンをクリックしてルーレットを開始します。ルーレットを最初からやり直す場合は「リセット」ボタンをクリックします。

  4. 「コピー」ボタンでコピーしたURLを保存していただくか、ブックマークをしていただき、再度同じURLにアクセスすることで事前に作成したルーレットを使うことができます。 ※URLを忘れた場合、作成済みのルーレットにアクセスできなくなりますのでご注意ください。

解決したい問題

一時期ほどではないですが最近はオンラインのイベントが増え、オンライン飲み会も一般的になりました。どこにいても交流できるオンライン飲み会ですが、初対面の人が多くて話題に困ってしまったり、話すタイミングを逃してしまい特定の人が話し続けてしまったりすることがあると思います。RouletteTalkでは話題と話す人の両方をルーレットで決められるので、全員に話す機会が回ってきます。 また、オンライン飲み会当日に話題をいくつも考えるのは大変ですが、RouletteTalkは作成したルーレットを保存できるので、事前にルーレットを作成して当日すぐに使い始めることができます。

技術スタック

言語、フレームワーク

DB

インフラ

  • Fly.io

テスト

CI

工夫したところ

ルーレット編集時のストレスを少なくする

RouletteTalkでユーザーが操作をするのは主に「ルーレットを作る」、「ルーレットを開始する」の2つだけなのですが、このうち特にユーザーが離脱する要因になりそうと思ったのは「ルーレットを作る」の部分でした。ルーレット編集時のストレスを軽減できるように、トークテーマと話す人の追加・編集・削除機能の実装にはHotwireのTurbo Streamsを使用しています。開発の途中までは、一か所の更新(フォームの表示など)はTurbo Frames、複数か所に更新が必要な場合はTurbo Driveを使うようにしていました。PC上でローカルで動かす分には特に問題なかったのですが、本番環境にデプロイして確認してみたところ登録・編集・削除時のレスポンスに課題がありました。そのため、複数か所の更新にはTurbo DriveではなくTurbo Streamsを使用して必要なところ以外は更新しないようにしたことでレスポンスも許容できるレベルとなり、操作感も良くなったと思います。

ログイン機能を付けない

ログイン機能によって提供できる機能が増えるメリットはあるのですが、一方でユーザー登録が使い始める一つの心理的なハードルになってしまうのではとも思っていました。利用シーンを考えても手軽に使えるサービスである方が良いと思ったので、RouletteTalkではログイン機能を付けないことにしました。ユーザーが作ったルーレットに誤って別のユーザーがアクセスしてしまう問題については、UUIDを使用して十分に長いURLを発行することにより対応しています。

苦労したところ

Hotwireの使い方、Stimulusの設計

今回のサービスを作るにあたって初めてHotwireを使いました。TurboもStimulusも非常に便利なライブラリなのですが、最初のうちは全く使い方が分からなかったので、公式のハンドブックやブログ記事などを読みながら徐々に使い方に慣れていきました。Hotwireの中で特に苦労したのはStimulusの設計です。どのようにコントローラを分割すれば良いのか、コントローラの命名(何を主語にすれば良いのか)など、あまり情報が多くないこともあり、かなり苦戦しました。Stimulusを使っている箇所の設計については今後も勉強しながら適宜見直したいと思っています。

ルーレットのテスト

ルーレットの開始についてはStimulusを使って実装しているのですが、こちらのシステムテストにかなり苦労しました。ルーレットが想定した角度で止まっているのかを検証するためにルーレットが停止したときの角度を取得する必要があったのですが、単純に何度に回転しているという角度が取得できるわけではなく、matrixの値から角度を計算する必要がありました。matrixのドキュメントに加え、易しめの数学の記事なども読みながらなんとか実装することができました。ただ、このテストのおかげでMathモジュールにこんなメソッドがあったんだという発見もあり、貴重な経験になりました(Math.#atan2も初めて使いました)。

今後追加したい機能

今後追加したい機能は、以下の2つです。

  • 作ったルーレットを配布できる機能
  • 直近でアクセスしたルーレットの一覧を表示する機能

一つ目のルーレットを配布できる機能については、複数テーブルに分かれるイベントで主催者が事前にトークテーマを設定したルーレットを各テーブルで使うシーンを想定したものです。二つ目の閲覧ルーレット一覧については、作成したルーレットが増えてきたときに管理を楽にするためです。どちらの機能もまだ考慮が必要なためファーストリリースには含めませんでした。今後使っていく中で、やっぱりあった方が良いとなれば追加したいと思っています。

さいごに

時間はかかってしまいましたが無事にサービスをリリースすることができました。開発に際してご協力いただきましたフィヨルドブートキャンプのメンターの皆さん、関わってくださった受講生の皆さん、本当にありがとうございました。今後も使いやすいサービスにしていけるよう頑張っていきたいと思います。

Vimをちゃんと使い始めて半年経った

この記事は「フィヨルドブートキャンプ Part 2 Advent Calendar 2023」21日目の記事です。 昨日はumizaruさんの「チェリー本の輪読会を終えて」でした。

adventar.org

Part1はこちら

adventar.org

はじめに

ここ半年ほど、家でコードを書くときはVimやNeovimをメインのエディタとして使っています。 Vim(Neovim)を本格的に使うようになって良かったことや逆に困ったことなどを書いていきたいと思います。

※以降はNeovimを含めて「Vim」と表記します。

Vimを使うようになったきっかけ

これまではVSCodeをメインのエディタとして数年使ってきて、Vimに関しては時々設定ファイルを修正するときなどに少し触る程度でした。VSCodeを使っていて特段困ることはなかったし、エディタを変えようとは思っていませんでした。 ところが、今年5月のRubyKaigiでVimキーバインドに絡めたネタがいくつか話されていた際、開場では笑いが起きているのに自分はあまりピンと来ていないということがありました。会場で一緒に笑えなかったのは少し悲しかったので、来年のRubyKaigiでVimネタが話されることがあったら今度は笑えるようになりたい、という変な動機でVimを使い始めることにしました。

ストレスなく使えるためにやったこと

意識せず使えるキーを増やす

Vimを使い始めるにあたってVimに関する記事やYoutubeの動画をいくつか見て、よく使うキーを調べました。10~20ほどのキーを覚えればひとまずストレスなく使えそうだということが分かったのですが、いきなり全て覚えて使おうとすると挫折しそうだったので、まずはカーソル移動のh j k lを意識せず使えるまでしばらく使ってみることにしました。カーソル移動に慣れてきたら「次はoO(新規行の挿入)を使ってみよう」という感じで数個ずつ意識せずに使えるキーを増やしていったところ、1~2ヵ月程でさほどストレスなくVimを使えるようになりました。

自分で少しずつカスタマイズする

Vimを本格的に使う場合は、独自キーマップの定義やプラグインを導入してカスタマイズしていくことになると思います。Vimを使い始めてから数週間は、vimrcを編集してキーマップやカラースキームを変更したり、vim-plugを使ってプラグインを一つずつ導入していきました。振り返ってみると、少しずつカスタマイズしていったことが結果的には良かったと思っています。当たり前ですが自分が変更したところしか変わらないので、「どこを編集したらどこが変わるのか」が分かりやすく、エラーが発生した際も原因を特定しやすくなります。 中には1つ入れるだけでIDEライクに使えるようになる、プラグインや設定がパッケージされたものもあります。これ自体は素晴らしいものですし、私自身も現在はAstroNvimというパッケージを使っています。ただ、個人的には最初から「全部のせ」なパッケージを使っていたら導入前からの変更点が多く、エラー発生時の原因特定も難しいため途中で挫折していたような気がします。

Vimを使って良かったこと・微妙だったこと

Vimに対する抵抗が無くなった

何かしら設定ファイルを変更するときなど、どうしてもVimを使わなければいけない場面があります。そんな時にこれまでは「VimじゃなくてVSCode使いたいなー」となっていたのですが、今はそこまで何とも思わずに使うことができるようになりました。

興味のある分野が増えた

Vimを使うようになって、Vimプラグインプラグインマネージャーについて興味を持つようになり、プラグイン関連の記事を読むようになりました。LSPについてもVimを触りだしてから初めて使うようになって仕組みを調べたりもしたので、技術への興味の幅が広がったと思います。

素のVimは使いづらい

プラグインやvimrcによってカスタマイズできるのがVimの良さだと思うのですが、自分が使いやすいように設定を変更しすぎると、たまに素のVimを使ったときにめちゃくちゃ使いづらいです。デフォルトのキーマップももっと覚えないといけないなと思います。キーマップの変更もデフォルトから離れすぎないようにした方が良いのかもと思ったりします。

日本語で文章を書くのはしんどい

コードを書く際は全く問題ないのですが、Markdown等で日本語をバリバリ書くときは全角と半角の切り替えが何度も発生するので結構しんどいです。色々やりようはあると思うんですが、今のところ日本語で文章を書くときはVSCodeMarkdownエディタを使っています。

おわりに

Vimネタで笑えるようになりたいという当初の目的は最初の1~2ヵ月くらいでほぼ達成できたと思うんですが、結果的にVimキーバインドが便利で使い続けています。今後また別のエディタを使うことになっても、Vimキーバインドは積極的に使っていきたいなと思っています。

AstroNvimで追加したプラグインが読み込まれない

AstroNvimでプラグインを追加する際、プラグインのインストールはできたのに読み込まれなくてつまずきました。

環境

  • WSL2(Debian)
  • Neovim v0.9.1
  • AstroNvim v3.34.4

結論

AstroNvimではプラグイン管理にlazy.nvimを使用していて、Lazy Loadingをデフォルトでtrue(ON)にしているため、読み込みのタイミングも合わせて設定する必要があります。
今回はvim-slimを入れて、slimファイルのときにシンタックスハイライトを効かせたかったのでft = "slim"を設定しました。

-- ~/.config/nvim/lua/user/plugins/user.lua

return {
  {
    "slim-template/vim-slim",
    ft = "slim",
  },
}

やったこと

プラグインのインストール

ドキュメントに記載の通りAstronvim/user_exampleをフォークして、以下のコマンドを実行します。

git clone https://github.com/<username>/<config_repo> ~/.config/nvim/lua/user

user/plugins/user.lua に追加したいプラグイン名を記述します。今回は、slimファイルでシンタックスハイライトを適用させるためのプラグインであるvim-slimを追加しました。

-- ~/.config/nvim/lua/user/plugins/user.lua

return {
  "slim-template/vim-slim",
}

Neovimを再起動し、インストール処理は問題なく実行されたのですが、slimファイルを開いてもシンタックスハイライトが効きません。

slimファイルでシンタックスハイライトが効いていない

<Leader>psプラグインのステータスを確認したところ、vim-slimがロードされていないようでした。

vim-slimがNot Loadedになっている

user.luaにロードタイミングの設定を追加

AstroNvimではlazy.nvimの設定をdefaults = { lazy = true }としていて、Lazy LoadingがデフォルトでONになっています。 そのため、プラグインを追加する場合は読み込みのタイミングを合わせて設定するか、プラグイン単位で遅延読み込みをOFFにする必要がありました。 上記ではロードのタイミングを設定していなかったため、いつまでもvim-slimが読み込まれなかった、というわけです。
AstroNvimのドキュメントにも以下のように記載されています。

CAUTION
By default we have Lazy.nvim enabling lazy loading for plugins. Because of this make sure to either include conditions for plugins to be loaded or make sure to add lazy = false to the plugin definition.

デフォルトではLazy.nvimがプラグインの遅延読み込みを有効にしています。このため、プラグインを読み込むための条件を含めるか、プラグインの定義にlazy = falseを追加してください。

今回はslimファイルを開いたタイミングでプラグインを読み込みたいので、ft = "slim"を追加します。

-- ~/.config/nvim/lua/user/plugins/user.lua

return {
  {
    "slim-template/vim-slim",
    ft = "slim",
  },
}

無事にslimファイルを開いたときにシンタックスハイライトが適用されました。

slimファイルでシンタックスハイライトが効いている

プラグインのステータスもちゃんとLoadedになっています。

vim-slimがLoadedに入っている

ft以外にもlazy.nvimでは以下のような設定が用意されています。 設定項目の一覧はlazy.nvimのreadmeに記載されています。

  • event
  • cmd
  • keys

補足:Lazy Loading(遅延読み込み)ってなに?

vim(Neovim)の起動時はプラグインを読み込まずに、特定のタイミング(xxxコマンドを実行したら、filetypeがxxxだったら等)で読み込むようにする設定。 必要な時に必要なプラグインだけを読み込むようにすることで、vimのパフォーマンスを上げることが目的のようです。

Ruby標準のRSSライブラリでRSS1.0、RSS2.0、AtomのフィードをDBに保存する

railsruby標準のrssgemを使用して、RSSフィードの取得・登録処理を実装した。

環境

やったこと

gemの追加

rssはbundled gemなので、railsで使う場合はGemfileに以下を追加してbundle installする。

# Gemfile

gem 'rss'

RSSのパース、DBへの登録

rssgemを使ってRSSをパースする場合はRSS::Parser.parseメソッドを使用する。 .itemsとすることで、オブジェクトの配列が返ってくる

# 戻り値としてオブジェクトの配列が返ってくる
RSS::Parser.parse('https://example.com/rss').items

パース後のオブジェクトはフィードの形式毎にクラスが異なるだけでなく、タイトルやリンクなどを取得する際に指定するプロパティも異なるため、フィードの形式毎に別の登録処理を実行する。
※フィードの形式毎にクラスを定義しても良い

# app/models/feed.rb

class Feed < ApplicationRecord
  def self.fetch_and_save(feed_url)
    # RSSをパース
    rss_items = RSS::Parser.parse(feed_url).items

    rss_items.each do |item|
      # プロパティの種類が異なるため、フィードの形式毎に登録処理を分ける
      case item.class.name
      # RSS1.0の登録処理
      when 'RSS::RDF::Item' then Feed.save_rdf_feed(item)
      # RSS2.0の登録処理
      when 'RSS::Rss::Channel::Item' then Feed.save_rss_feed(item)
      # Atomの登録処理
      when 'RSS::Atom::Feed::Entry' then Feed.save_atom_feed(item)
      end
    end
  end
  .
  .
  .

RSS1.0の登録処理

RSS1.0、およびrssgemで対応しているRSSのモジュール(2023年9月2日現在)では、記事ごとに画像を設定できないようなので、RSS1.0では画像のURLにnilを設定する。

# app/models/feed.rb

def self.save_rdf_feed(rdf_item)
  Feed.create(
    title: rdf_item.title,
    url: rdf_item.link,
    summary: rdf_item.description,
    image_url: nil,
    published_at: rdf_item.dc_date
  )
end

RSS2.0の登録処理

enclosureに関してはオプションで、当該xmlに存在しない場合がある。そのためrss_item.enclosure&.urlとして、存在しないときは画像のURLにnilを設定して登録する。

# app/models/feed.rb

def self.save_rss_feed(user, rss_item)
  Feed.create(
    title: rss_item.title,
    url: rss_item.link,
    summary: rss_item.description,
    image_url: rss_item.enclosure&.url,
    published_at: rss_item.pubDate
  )
end

Atomの登録処理

AtomではRSS2.0のenclosureのように画像の場合も明確にタグの種類が異なるわけではなく、複数存在するlinkの一つとして画像が設定されている。そのため、linktypeプロパティにimageが設定されているものを探して画像のURLを取得する。こちらもRSS2.0と同様、存在しない場合があるため&.hrefとしている。

# app/models/feed.rb

def self.save_atom_feed(user, atom_item)
  Feed.create(
    title: atom_item.title.content,
    url: atom_item.link.href,
    summary: atom_item.content.content,
    image_url: atom_item.links.find { |link| !link.type.nil? && link.type.include?('image') }&.href,
    published_at: atom_item.published.content
  )
end

赤い公園の好きな曲をいくつか書いてみる(赤い公園アドベントカレンダー23日目)

はじめに

こちらは赤い公園アドベントカレンダー23日目の記事です。

僕は趣味でギターを弾くのですが、理論的なところはあまり分からないので、とにかく赤い公園で好きな曲を5曲ほど書いてみたいと思います。ギターのカッティングが好きなので、カッティングがかっこいいと思った曲が多い気がします。

Highway Cabriolet

Highway Cabriolet

Highway Cabriolet

  • provided courtesy of iTunes

music.apple.com

新体制になって2曲目の曲です。PVがYoutubeに公開されて、一度聴いただけでどハマりしたのを覚えています。何となくレトロっぽさを感じる全体の雰囲気がとても良い感じです。個人的に、2番サビの直前に入るカッティングが好きすぎます。

黄色い花

黄色い花

黄色い花

  • provided courtesy of iTunes

music.apple.com

ギターのフレーズは結構シンプルですが、聴いていてすごく心地良い。聴けば聴くほど癒されて、元気になれる曲です。ライブで初めて知って、「こんなかわいい曲あるんだ!」となりました。

ナンバーシックス

ナンバーシックス

ナンバーシックス

  • provided courtesy of iTunes

music.apple.com

明るい曲調で、コーラスが聴いていて楽しい曲です。サビで入ってくる、(たぶん)アコギの音が気持ち良くてノリノリになれます。途中で入ってくる男性のコーラスはどなたなのだろう…

闇夜に提灯

闇夜に提灯

闇夜に提灯

  • provided courtesy of iTunes

music.apple.com

イントロから最高にかっこいい曲で、結構ザラザラした感じの歪みサウンドがまた良いです。イントロに加えて、「大暗中 want you...」あたりの歌っているようなギターが好きです。

TOKYO HARBOR feat.KREVA

TOKYO HARBOR (feat. KREVA)

TOKYO HARBOR (feat. KREVA)

  • provided courtesy of iTunes

music.apple.com

とにかくおしゃれで、ビールを片手にゆらゆらしながら聴いていたくなるような曲です。全体的に落ち着いた雰囲気で、各楽器それぞれの音が結構ちゃんと聞こえるので、どれか一つの楽器に集中して聴くのも楽しいです。すごい好みなので、一度はライブで見てみたかったなと思います。

まとめ

赤い公園の好きな曲についての感想や好きなポイントを書いてみました。まとまりのない文章になりましたが、少しでも共感してもらえたら嬉しいです。

これからも赤い公園を聴き続けていきたいと思います。