『初めてのLT会 Vol.17』へ登壇しました!当日までを振り返ります✨

この記事はフィヨルドブートキャンプ Advent Calendar 2025の23日目の記事です。

昨日はLEFさんの『Rails の find はどう動く? Active Recordの内部実装を見てみよう!』でした!

はじめに

こんにちは!フィヨルドブートキャンプ(以下FBC)で勉強中のゆーかです。

先日、FBC内オンラインイベント「⚡️初めてのLT会 Vol.17」に登壇しました!

主催者の方からお声がけをいただき、是非やりたいと意気込むも、スライド作成も久々だしテーマも未定、準備ゼロの状態からのスタートでした。

それでも無事に当日を迎えられたので、これからLTに挑戦する方の参考になればと思い、準備の流れと当日の感想をまとめました。

LT会の準備

発表テーマを決める

今回のテーマは【情熱を持っていること】でした。

プログラミングの知識はひよっこなので情熱的に語れるほどでは‥と思っていましたが、その人の興味のあることを知りたいので非テック系も大歓迎だと聞き、それならばと参加表明しました。

今回私が選んだテーマは『睡眠負債について』です!

ちょうど、私の好きなにじさんじライバーの一橋綾人先生が睡眠に関する動画をいくつか出していて、そこからこのワードに興味を持ちました。

youtube.com

こちら当日発表したスライドとなります!

speakerdeck.com

その他の候補はこんな感じでした:

  • 睡眠について(入眠するまで)
  • 明治〜大正の文豪の豆知識
  • 明治後期〜昭和初期の歴史
  • 昭和の映画から見る日本人の振る舞い・言葉遣い
  • カナヅチがスイミングスクールに通い、3ヶ月で泳力検定に挑む話(これは別途ブログに書きます)

資料を探す

今回は学術寄りの内容だったので、間違った情報を伝えないよう入念に下調べをしました。

主に行ったことは以下です。

  • 睡眠に関する本を片っ端から読む(図書館とKindle unlimitedをフル活用しました)
  • 信頼できる参考サイトを探す
  • YouTube睡眠負債についての動画を探す(こちらはあまり収穫はなかったです)

スライドの最後に載せた参考サイトはこちらです。

発表内容をまとめる

資料が揃ったので、次は発表の構成をざっくり考えました。

今回の構成は「睡眠負債とはなにか?→負債があるとどう自分に影響するか→どうしたら解決するか」という流れにしました。

メインに据えたのは「どうしたら解決できるのか」 の部分です。

ただ知識を並べるだけではなく、聴衆の興味をひける様に自分ごととして考えてもらえるかを意識して実体験を交えながら一緒に考える形にしました。

工夫した点としては、 やりがちな解決方法を2つのプラン(一気に返済する方法、休日に返済する方法)として提示したことです。

少しでも身近に感じられるように、を意識しました。

起承転結のある発表用の台本が完成したので、次は発表練習をして削る作業をしました。

ちなみに私が台本を作る理由は、スライドを見ながらアドリブで話すとつい余計なことまで喋って時間オーバーしがちだからです。

ここまでしか話してはダメ、と決めて自分を抑制しました😂

仮台本で発表練習をして内容を清書していく

この時点では制限時間も未確定だったため、ここで時間を調節しました。

本番をイメージして最初から読み、不要な部分を削いだり不足分を足したりして台本を清書していきました。

私の場合は、こんな流れでした。

  1. 完成した台本を通しで読み、時間を測る。
  2. 長すぎたので不要な部分を大幅にカットする。
  3. 内容の違和感をチェックする。(余計なアドリブが多いことに気づき削る)
  4. 話し方を修正する。(早口・声の硬さを抑える、強調したい言葉に緩急をつける、アドリブは全削除)
  5. 内容が体に馴染んできたので、スライド作成へ進む。

このあたりまで来ると、「この時にはこんなスライドが欲しいな」というイメージが自然と浮かんできました。

スライドを作る

使用したアプリ

今回はKeynoteで作りました。

FBCの過去のLT会登壇者が「登壇後のブログ」を投稿しているので、そこにスライド作成の苦労やノウハウが詰まっていました。宝の山や‥✨

実際のスライドも掲載されているので、一度に沢山のスライドを見られてとても参考になりました!

スライド作成で意識したこと

  1. 1枚に情報を詰め込みすぎないようにする。その代わりに枚数を多くする。

  2. 文字の定位置を決める。 横書きの場合左から右へ読むので、文字は基本左端か真ん中に置きました。

  3. とにかくシンプルに。 文字は基本黒系、大事な部分のみピンク系。今回は背景色に合わせて文字色を少し薄めの黒(墨色)にしました。 背景は単色のスカイブルーにしました。色々やりたくなりましたが、デザインの知識もないし、今回はシンプルさを重視しました。

  4. 小さい画面でも文字が読めるようにする! 作成時にKeynoteのウィンドウを最小にしてスライドを作成しました。 そのため小さい画面で見ても文字がはっきりと読めるようになりました。

本番までひたすら発表練習

本番の約1週間前にスライドが完成しました!

ここからは時間の許す限り発表練習をしました。

「こちとら忙しい社会人だい!そんな暇はないんだよ!」という方もいるかと思いますが、

せっかくここまで頑張って作り上げたのに、本番で噛みまくったり、緊張で頭が真っ白になってしまっては勿体ないです!

資料でも十分情報は伝わりますが、LT会の醍醐味は その人の言葉で伝えることだと思っていますので、ここは是非練習してみてください☺️

私が実践した練習方法はこちらです。

  1. 毎回、本番を想定して話した。 ポイントは観客を想像しながら話すことです。 今回は内容のボリュームが多いのでつい早口になりがちでしたが、ゆっくりはっきり、そして威圧しないよう穏やかに話すよう意識しました。

  2. スマホで録音をする。 自分の声を聞くって超恥ずかしいですが、やればやるだけ良くなっていくし、自分をコントロールできるようになります。

  3. PCで録画をする。 MacのQuickTimePlayerを使用し、画面収録で録画しました。 当日を想定し、PCは全画面スライド、右手はスライドを捲るための操作、左手は台本(スマホ)を持ち、なるべくカメラ目線で最初から最後まで発表しました。 録画を見直すことで、自分の発表がよく分かるのでとても良いです。

そして迎えた当日

当日はとても落ち着いて発表できました〜〜🎊

自分が発表した内容を、他の方が考えて言葉にしてくださるのを見ると、「やってよかった…!」という気持ちが込み上げてきて、とても嬉しいです😊

ひとつ意外だったのは、思った以上に「怖かった」と言われたことです笑

私の予想では、「へぇ〜タメになるなぁ〜」くらいの軽い気持ちで見てもらえるかと思いきや、当日のコメントや感想文で結構な人が恐怖を感じる内容だったそうです😂

(ボンヤリする黄昏時にすみませんでした笑)

ですが、終了後には色んなところから「知らなかった!」「知見を得た!」と声をかけていただきとても嬉しかったです。

完璧でなくても、自分が面白いと思ったことを共有するだけで、誰かの学びにつながるのだと実感しました。

おわりに

準備は大変でしたが、それ以上に登壇して得られたものは大きかったです!

LTは登壇するだけで十分価値があります。もし少しでも興味があるなら、ぜひ一歩踏み出してみてほしいです。

(次は自分でLT会を主催するのも面白そうだなと思っています笑)

【Rails初心者】疑問に思ったRailsメソッドを深掘りしてみた

これは「Ruby/Rails Advent Calendar 2025」21日目の記事です。 qiita.com

はじめに

私はプログラミング未経験から、Railsエンジニアとして就職を目指しているゆーかと申します。

普段はフィヨルドブートキャンプにて学習を進めています。

さて、今年9月から念願のRailsプラクティスに入り、Railsガイドを1から読み進めてみたのですが、初心者の私にはすべてが新鮮でした。

link_toメソッドについて疑問が出た

Rails をはじめよう を読みながら、 link_to メソッドを使うとリンクが簡単に作れると知り、早速試してみました。

link_to を使わない場合。

<div id="products">
  <% @products.each do |product| %>
    <div>
      <a href="/products/<%= product.id %>">
        <%= product.name %>
      </a>
    </div>
  <% end %>
</div>

link_to を使った場合。

<div id="products">
  <% @products.each do |product| %>
    <div>
      <%= link_to product.name, product %>
    </div>
  <% end %>
</div>

一行でスッキリ書けました。しかし、なぜ第2引数に product と書くだけで /products/1 に変換されるのでしょうか?

結論

link_to メソッドの裏側で最終的に呼ばれていたのは polymorphic_url メソッドでした。

これは 「渡されたオブジェクトに応じて自動的に正しいURLを生成する」 メソッドです。 これによって @product が /products/1 に変換されていたことがわかりました。

Action View ヘルパー を確認すると、 link_to の説明にはこう書かれています。

背後の url_for で得られたURLへのリンクを生成します。

link_to "Product", @product
 # => <a href="/products/1">Product</a>

link_to の内部では url_for が呼ばれているということです。

url_forメソッドを読む

url_for のソースは actionpack gem に定義されています。

bundle open actionpack で中を開いて確認してみました。

def url_for(options = nil)
  full_url_for(options)
end

def full_url_for(options = nil)
  case options
  when nil
    _routes.url_for(url_options.symbolize_keys)
  when Hash, ActionController::Parameters
    ...
  when Array
    polymorphic_url(components, components.extract_options!)
  else
    HelperMethodBuilder.url.handle_model_call self, options
  end
end

今回options の中身は ActiveRecord オブジェクト(@product) なので、else に入り、HelperMethodBuilder.url.handle_model_call(self, options) が実行されます。

HelperMethodBuilder.url.handle_model_callとは

actionpack/lib/action_dispatch/routing/polymorphic_routes.rb に定義されています。

def handle_model_call(target, record)
  if mapping = polymorphic_mapping(target, record)
    mapping.call(target, [record], suffix == "path")
  else
    method, args = handle_model(record)
    target.public_send(method, *args)
  end
end

もし polymorphic_mapping が見つかった場合は、 その返り値を mapping に代入し、mapping.call で実行します。

このとき返される値が「/products/1」になるそうです。

polymorphic_mapping と mapping.call とは?

polymorphic_mapping

渡されたオブジェクト(例: @product)に対応するルーティング情報(Procオブジェクト)を探すメソッドです。 Railsは「このモデルは /products/:id に対応している」と判断できるように、 内部でその対応表(マッピング)を保持しています。

mapping.call

polymorphic_mapping で取得した Proc を実行する部分です。 つまり「このモデルのURLを実際に生成する」処理がここで行われます。

実際の Proc の中では、次のような呼び出しが行われています。

Proc.new do |context, records, path|
  context.polymorphic_url(records, path: path)
end

つまり最終的に polymorphic_url([record]) が呼び出され、 URLが /products/1 のように生成される、とのことです。

処理の流れを整理する

link_to product.name, product
↓
url_for(product)
↓
full_url_for(product)
↓
HelperMethodBuilder.url.handle_model_call(self, product)
↓
polymorphic_mapping(self, product) でマッピングを取得
↓
mapping.call(target, [record], suffix == "path")
↓
polymorphic_url([record])
↓
/products/1 を返す

終わりに

link_toメソッドの裏側で、これほど多くの処理が行われていることには正直驚きました。

実際にはRailsがオブジェクトとルーティングを結び付け、状況に応じてURLを生成していることが分かり、理解が一段深まりました。

今回はヤクの毛刈りを沢山してしまいましたが、その過程でRails内部の仕組みを追えたのは大きな収穫でした。Railsは本当に奥が深いですね。

【HTTP】telnetを使ってGETメソットをリクエストする

フィヨルドブートキャンプでプログラミングを勉強中です!

telnetを使ってHTTP通信がどの様に行われているか体験したので記録として残しておきます。

telnetをインストールする

まず、MacOSの初期状態にはtelnetが入っていないので、telnetをインストールします。

一応確認の為に、ターミナルからtelnetコマンドを打ちましたが案の定コマンドがないと返されました。

zsh: telnet command not found

コマンドをインストールします。

Homebrewが最新でないこともあるので先に更新して最新にしておくと安心です。

brew install telnet

これでインストール完了です。

telnetで通信する

telnetコマンドで開きます。

❯ telnet
telnet> 

実験に使うサイトは、FBCで用意してくれたダミーサイトを使用します。

dummy-bootcamp-fjord-jp.herokuapp.com

telnet dummy-bootcamp-fjord-jp.herokuapp.com 80

GETメソットでリクエストしたいときは下記のフォーマットになります。

GET /URLのパス部分(サーバー名の部分) HTTP/1.1
Host: ドメイン(サーバー名)


GET / HTTP/1.1
Host:dummy-bootcamp-fjord-jp.herokuapp.com

サーバーからレスポンスが返ってきました。

HTTP/1.1 200 OK
Server: Cowboy
Date: Sat, 29 Feb 2020 07:23:43 GMT
Connection: keep-alive
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: text/html; charset=utf-8
Etag: W/"52f5215d44e2cdef685be8f896c1b174"
Cache-Control: max-age=0, private, must-revalidate
Set-Cookie: _dummy_session=Vy0x3xsWhBG0j8IRjd%3D; path=/; HttpOnly
X-Request-Id: 0ffc5007-9d86-4a45-973c-70ca55dc6850
X-Runtime: 0.128977
Transfer-Encoding: chunked
Via: 1.1 vegur

ba9a
<!DOCTYPE html>
<html>
以下HTMLが続く…

ステータスは200 OKでした!無事にGETできました!

telnetを終了したいときはqを入力します。

参考サイト

【sinatra・Rails】paramsのキーはハッシュでも文字列でもOK

SinatraRailsを学習中に、フォーム送信されたデータを受け取るために使うparamsでは、キーをシンボルでも文字列でも扱えることを知りました。

Action Controller の概要 - Railsガイド

paramsハッシュは、Rubyの単なるHashではなく、ActionController::Parametersオブジェクトである点にご注意ください。このオブジェクトはRubyのHashのように振る舞いますが、Hashを継承していません。また、paramsをフィルタリングするためのメソッドが提供され、シンボルキー:fooと文字列キー"foo"が同じものと見なされる点もHashと異なります。

この2つは同じ結果になります。

params[:foo]
params["foo"]

シンボルを使うと以下のように使用できます。(sinatraを使っています)

post '/memos' do
  
  # 新しいIDを発行
  id = record_data['last_id'] += 1
  # キーをシンボルで取得
  title = params[:title]
  message = params[:message]
  record_data['memos'] << { 'title' => title, 'message' => message, 'id' => id }
  # JSONデータに追加して保存
  File.open('db.json', 'w') { |file| file.write(JSON.generate(record_data)) }

  redirect '/'
end

またHashのようにも振る舞えるので、sliceメソッドを使ってコードを短縮できます。

sliceメソッドを使うと、ハッシュから必要なキーだけを取り出すことができるので不要なデータを除外して扱うことができます。

post '/memos' do
  new_memo_data = params.slice(:title, :message).merge('id' => id)
  record_data[:memos] << new_memo_data

  File.open('db.json', 'w') { |file| file.write(JSON.generate(record_data)) }

  redirect '/'
end

◯まとめ

  • paramsは見た目はハッシュだが、実際はActionController::Parametersオブジェクトなので、シンボルキーでも文字列キーでも同じように値を取得できます。

  • sliceメソッドを使えば、必要なキーだけを取り出してコードをスッキリ書けます。

参考サイト

【初学者向け】railsのparamsについて分かりやすく解説してみた #Ruby - Qiita

【Rails】I18n.locale=とI18n.with_localeの違いとは?

Railsガイドの「Rails国際化 (I18n) API」を読んでいて、ロケールの切り替え方が2種類あったので違いを調べてみました。

I18n.locale=

現在のスレッド全体のロケールを変更します。

before_action :set_locale

def set_locale
  I18n.locale = params[:locale] || I18n.default_locale
end

Rails5.2までこの機能が使われていましたが、時々ロケールの設定が漏れてしまうこともあるため、6.0以降からはI18n.with_localeを使うことが推奨されています。(ガイドによると、前回リクエストした時のロケールがそのまま次のリクエストに反映されてしまうことがあるのだそうです。)

I18n.localeの設定がすべてのコントローラで一貫していないと、同じスレッドやプロセスによって処理される今後のリクエストにI18n.localeが漏出する可能性があります。たとえば、あるPOSTリクエストでI18n.locale = :esを実行すると、ロケールを設定していないコントローラで以後のすべてのリクエストに効いてしまいます。こうした理由から、I18n.locale =の代わりに、漏出が発生しないI18n.with_localeを利用することもできます。(railsガイドより)

I18n.with_locale

一時的にロケールを切り替えて、そのブロック内だけ有効にします。

around_action と組み合わせれば、各リクエストを処理するときだけロケールを切り替え、処理が終わったら自動で元に戻ります。

around_action :switch_locale

def switch_locale(&action)
  locale = params[:locale] || I18n.default_locale
  I18n.with_locale(locale, &action)
end

I18n.with_localeを使用するときは、around_actionと組み合わせて使いましょう!

参考記事

Rails 国際化(I18n)API - Railsガイド

Rails国際化 (I18n) API - Railsガイド

RailsでI18n.localeを書き換えていたらたまに言語設定がバグる問題に遭遇した #Rails - Qiita

i18nで多言語化する設定 - 時々とおまわり

休会から復帰しました!再始動します🚙【フィヨルドブートキャンプ】

しばらく休会しておりました🦧

家庭の事情で3ヶ月ほど学習をお休みしておりました。 FBCは自習形式のスクールなので一応休会せずとも学習はお休みできますが、一旦きっぱり離れようと思い休会することにしました。(その間月会費もかかるしね…!)

お休み中は新生活に慣れることに全集中しておりました!長年入院していた子どもが退院し、家族全員で久しぶりに過ごす毎日は嬉しさもありつつもなかなか大変で、特に子どもの食事に頭を悩ませていました💦

他にも子どもの発達について調べたり、児童館へ行ったり、毎日スーパーで買い物したり(思い通りに買い物できないのが大変💦)とバタバタしながらも幸せな日々でした。

勉強のこと

休会後しばらくは勉強のことを考える余裕はありませんでした😅

生活が落ち着いてきた頃、ふと「また勉強したいな」と思うようになり、久しぶりにPCを開いてみました。

休会前にやってた内容はもう忘れてるかな〜、と思いきや、10分ほどでスッと記憶がよみがえり、1時間くらい無心でコードを書いていました。

あの脳が冴える感覚がすごく気持ちよくて、「ああ、この時間が好きだったな」と勉強がある生活が楽しかったことを思い出していました。

勉強のモチベーションは戻りそう?

バリバリ戻っています!🤩

スパッと離れていたのが功を奏し、自然とまた戻りたくなったみたいです。毎日開いていたFBCの日報もすごく恋しくなりました。

今月はKaigi on Railsがあるのと、ちょうどプラクティスがRails付近だったので、お休みの後半はのんびりとRailsガイドを触っておりました。

休会後にやること

もっと質問をします!! 休会前は全然質問できず質問力が鍛えられていないので、再開後はガンガン質問していきたいです!

今後は、また勉強を習慣化することから始まりますが、すでに学習再開のスタートは切れていますので、FBC卒業&エンジニア就職に向けて、また走り出していこうと思います!🏃🏻‍♀️

【Ruby】findメソッドの返り値は元のオブジェクトを参照していると知って驚いた

findメソッドの返り値が元の配列の要素そのものであることを知ってめちゃくちゃ驚いたので記録しておきます。

users = [
  {"id" => 1, "name" => "Yuka", "address" => "Tokyo",  "tel" => "03-xxxx-xxxx"},
  {"id" => 2, "name" => "Yuuta", "address" => "Osaka", "tel" => "080-xxxx-xxxx"},
  {"id" => 3, "name" => "Kazuki", "address" => "Nagoya", "tel" => "052-xxx-xxxx"}
]

# id=3のユーザーを探し、変数target_userに代入する
target_user = users.find { |u| u["id"] == 3 }

# 住所と電話番号を更新
target_user["address"] = "Hokkaido"
target_user["tel"] = "080-9999-9999"

# 結果を確認
p users
#=>
users = [
  {"id" => 1, "name" => "Yuka", "address" => "Tokyo",  "tel" => "03-xxxx-xxxx"},
  {"id" => 2, "name" => "Yuuta", "address" => "Osaka", "tel" => "080-xxxx-xxxx"},
  {"id" => 3, "name" => "Kazuki", "address" => "Hokkaido", "tel" => "080-9999-9999"}
]

target_userを変更しただけでusersも変更されています。

findで取得した要素を直接変更すれば、元の配列の要素も変更されるのは、findメソッドの返り値は元のオブジェクトを参照しているからでした。

オブジェクトidを比較すると全く同じ値でした。

users[2].object_id #=> 225000
target_user.object_id #=> 225000

こんな簡単に元のオブジェクトを変更できたとは‥。取得した値は別のオブジェクトであるとなぜか決めつけていたので目から鱗でした。