Railsでpathによる言語設定を行う

ゴール

/books/new # 日本語ページ
/en/books/new # 英語ページ

でアクセスできる。

やること

config/routes.rbに以下を追加。localeをパスに含めても含めなくてもアクセスできるようになる。jaは不要ならつけない。

scope "(:locale)", locale: /en|ja/ do
  resources :books
end

config/initializers/locale.rbに以下を記述する。

I18n.available_locales = [:en, :ja]

I18n.default_locale = :ja

application_controller.rbに以下を追加。

class ApplicationController < ActionController::Base
  around_action :switch_locale

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

これで言語設定を切り替えることができる。コントローラでputs localeでログを出すと実際に切り替わっていることがわかる。/en/をつけるとlocaleが:enになっている。つけないとデフォルトの:jaになる。

言語切り替えボタンをつける

ユーザーが言語を切り替えられるように切り替え用のボタンをヘッダーにつける。English/日本語とか。

<%= link_to 'English', url_for(locale: :en) %>
<%= link_to '日本語', url_for(locale: nil) %>

ymlファイルの作成

config/locales/en.yml

en:
  hello: "Hello world"

config/locales/ja.yml

ja:
  hello: "こんにちは"

表示

言語を切り替えたいerbファイルで

<%= t("hello") %>

参考サイト

SentryでRailsのエラーをモニタリングする

個人開発のRailsのプロジェクトが増えてエラーに気付けないことがありそうなのでSenrtyを使ってみる。今回は無料で使える範囲で使用する。

Sentryに登録

まずはSentryにアクセスしてアカウントの登録を行う。

プロジェクトの作成

Railsを選択する。

Railsの設定

公式ページのConfigure Rails SDKを参考に必要なGemを入れる。Gemfileに以下を追加してbundle install.

gem "stackprof"
gem "sentry-ruby"
gem "sentry-rails"

config/initializers/sentry.rbファイルを作成する。dsnはcredentialに書いた。コードをオープンにしたり他の人が見る場合はdsnを直に書くのは微妙かもしれない。

Sentry.init do |config|
  config.dsn = Rails.application.credentials.sentry_dsn
  config.breadcrumbs_logger = [:active_support_logger, :http_logger]

  # Set traces_sample_rate to 1.0 to capture 100%
  # of transactions for performance monitoring.
  # We recommend adjusting this value in production.
  config.traces_sample_rate = 1.0
  # or
  config.traces_sampler = lambda do |context|
    true
  end
  # Set profiles_sample_rate to profile 100%
  # of sampled transactions.
  # We recommend adjusting this value in production.
  config.profiles_sample_rate = 1.0
end

heathページを作成

意図的にエラーが発生するページを作成する。

raise StandardError.new('test error')

エラーを発生させるとSentryにエラーが送られ、メールが届く。

Javascriptのエラー検知

RailsのエラーができたのでJavascriptのエラーも検知する。フロントの開発が多いとjsが原因で動かないが開発者は気づかないみたいなことが発生するのでjsのエラー検知もかなり大事。

Sentryでプロジェクトを作成する

左のメニューからProjects->Create Projectを選択する。

BROWSER JAVASCRIPTを選択してプロジェクトを作成する。

frameworkを使うか選択できるが、今回は選択しない。VueやReactを使っていたら選択した方が良い(と思う)。

Railsのjavascriptの設定

healthページを作成し、ボタンを押したらJSのエラーを発生させる。

erbファイルにscriptタグを追加。idはユーザーにバレるけど気にしなくて良いか…

<script
  src="https://js.sentry-cdn.com/649179e.min.js"
  crossorigin="anonymous"
></script>

ページにアクセスするとSentryにイベントが送られ、エラーが発生するとメールが来る。

終わりに

とても簡単に設定できた。Sentryすごい!

Railsをローカルでproduction指定で立ち上げたときのエラー

エラー内容

本番環境で動かす前にローカルでproductionを指定して動かしたら以下のエラーが出た。

HTTP parse error, malformed request: #<Puma::HttpParserError: Invalid HTTP format, parsing fails. Are you trying to open an SSL connection to a non-SSL Puma?>

原因

原因はSSLでアクセスする必要があるのにhttpでアクセスしているからだ。

解決策

config/environments/production.rbのforce_sslをfalseにすれば良い。

config.force_ssl = true

他の解決策

ローカル環境でもsslでアクセスした方が良いかもしれない。やる方法はいくつかあるが今回は採用しない。

VPSでdockerを使ったRailsサーバーを立てる

strong engineer

OSのバージョンはUbuntu 22.04.3。Nginxのインストール方法はこちら

必要なソフトのインストール

Dockerのインストール

こちらのサイトをそのまま実行すれば良い。

$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ apt-cache policy docker-ce
$ sudo apt install docker-ce
$ sudo systemctl status docker

GitHubからソースコードをインストールする

$ cd /var/www
$ git clone https://${GIT_USER}:${GIT_TOKEN}@github.com/${GIT_REPOSITORY}

Railsを起動する

$ docker compose -f docker-compose.production.yml build
$ docker compose -f docker-compose.production.yml up -d

参考サイト

リアルタイムでキーボード入力を表示する: KeyCastrの使い方

パソコンの使い方を説明するためにキーボードの入力を画面に表示してみる。

インストール

GitHubのKeyCastr を参考にそのまま実行する。

brew install --cask keycastr

設定

Security & Privacyから許可をすると入力時に画面に出力される。

KeyCastrのアプリを開いて文字の大きさなどを設定できる。

ドラッグ&ドロップでどこに表示するかを変更できる。

WebサイトのURLとタイトルをコピペしてブログに貼り付ける方法

urlCopy

ブログを書くときにWebページのリンクを挿入することはよくある。ページのタイトルをテキストで入力してURLをリンクとしてコピペするのは少し手間なので、一発でページタイトルとURLをコピペする。

動画

YouTubeにも解説動画をあげています。動画の方が見やすい方はこちらをご覧ください。

やり方

Chromeの拡張機能であるCreate Linkを追加する

Create Linkのページ: https://chromewebstore.google.com/detail/create-link/gcmghdmnkfdbncmnmlkkglmnnhagajbm?hl=ja

フォーマットを決める

今回はHTML形式のフォーマットをしているす。

<a href="%url%">%htmlEscapedText%</a>

他にもmarkdown形式など自由に設定できる。

ショートカットを割り当てる

chrome://extensions/shortcutsからショートカットの設定ができる。他で使わない覚えやすいショートカットならなんでも良い。

[Pythonで未来予測] AIを使って株価や販売量を未来予測する方法を解説!

strong engineer

Pythonを使って過去のデータから未来を予測する方法を解説します。YouTubeにも投稿しているので動画の方が見やすい方はぜひ動画でご覧ください!

YouTube: [Pythonで未来予測] AIを使って株価や販売量を未来予測する方法を解説!

概要

未来の株価を予測するために、過去のデータをPythonのstooqというライブラリを使って取得します。取得したデータをもとにpmdarimaというAIのライブラリを用いて学習を行い、学習したモデルを使用して未来の株価を予測します。

青色の線の過去のデータかAIが予測した未来のデータを緑色の線で描いています。

今回使用したコードはGoogle ColabというブラウザからオンラインでPythonが実行できる環境で公開しています。以下のリンクからアクセスして実際に動かしながら確認することで理解が深まると思います。

https://colab.research.google.com/drive/1RIouiTq43u1QqD6xA6aurLgCFTMHEi60

やること

pmdarimaのインストール

https://colab.research.google.com/drive/1RIouiTq43u1QqD6xA6aurLgCFTMHEi60

株価データを取得

from pandas_datareader.stooq import StooqDailyReader
from datetime import datetime

start = datetime(2023, 11, 1)
end = datetime(2024, 2, 1)
brand = '1306.JP' #TOPIX
stooq = StooqDailyReader(brand, start=start, end=end)
data = stooq.read()

AIを使って学習

# 学習
train = data.Close.to_numpy()
train = np.flip(train) # 時刻が古い方から新しい方の順番にする
model = pm.auto_arima(train, d=2, seasonal=False, max_p=6)

AIを使って未来を予測し、グラフに表示する

import matplotlib.pyplot as plt
# 予測
p = 12
forecasts = model.predict(p)

# グラフ表示
x = np.arange(61+p)
plt.plot(x[:-1*p], train, c='blue')
plt.plot(x[-1*p:], forecasts, c='green')
plt.show()

終わりに

正しい未来を正確に予測することは難しいですが、過去のデータから未来を予測するのはAIの得意分野の一つです。予想以上に簡単に実行できるのでみなさんもぜひ試してみてください。Google ColabのコードYouTubeの動画も参考にしていただきたいです。

ドメイン移管: Google DomainsからCloudflare Registrarへ

バグと戦うエンジニア

2023年9月7日にGoogle DomainsがSquarespaceに買収されてしまった。重い腰を上げてCloudflare Registrarに移管する。

Google Domainsは安くて使いやすくて好きなサービスだったので買収されたのはとても残念だが仕方ない。

ドメインサービス選定

Google Domainsに変わるサービスとしてはAmazon Route 53やさくらインターネットなど多くのサービスがある。今回は次の4つのことを考えてCloudflare Registrarを選んだ。長期的に使えそう・人気がある(ググって記事が見つかる)・海外サービス・安い。

海外サービスを使うことを当たり前にしたいのであえて今回は海外サービスにした。日本に住んでいることなどを考慮せず対等に比較して日本のサービスが良ければ日本のサービスを使うが、日本に住んでいるという理由だけで日本のサービスを使うのは長期的によくない気がしている。

変更したいこと

  • DNS設定
  • ドメイン管理
  • メール管理

やること

whoisで現状確認

すでにRegistrarはSquarespaceになっていた。

$whois example.com
...
Registrar: Squarespace Domains II LLC
Name Server: NS-CLOUD-B4.GOOGLEDOMAINS.COM
...

Cloudflareのアカウント作成

アカウント作成ページからアカウントを作成する。メールが来るので認証する。

DNSの移行

CloudflareとGoogle Domainsの設定を行う。cloudflareは無料プランを選択した。

Cloudflareでサイトを追加してDNSレコードを追加する。DNSレコードが全て反映されない時はGoogle DomainsからBIND形式でエクスポートしてCoudflareでインポートする。

Google DomainsでCustom name serversを設定する。これらの設定に切り替えるをクリックする。

Googleの設定をしたらすぐにcloudflareからメールが届いた。whoisで確認するとName Server:がcloudflareに変わっている!

サイトとcloudflareのProxy statusで二重にsslの設定をしているとおかしくなる。cloudflareのProxy statusはオフにすれば直る。

ドメインの移管

google domainsで移管を許可する。登録の設定からドメインの登録のドメインロックをオフにする。許可ができるまで数時間待つ場合もあるみたい。今回は2時間くらい待ったら先に進めた。

Cloudflareで支払い方法を設定する。

確認コードを入力して届いたメールから承認をすると移管が完了する。メールが届くのは数分待つこともある。

whoisコマンドで確認するとRegistrarがCloudflareになっている。

$ whois example.com
Registrar: Cloudflare, Inc.

メールの転送設定

カスタムドメインのメールアドレスをgmailで受信で可能にする。

Email Routingからカスタムアドレスを追加する。googleの設定がある場合はcloudflareの管理画面から削除する。

Google Domainsからはドメインが消える。

gmailから送信ができることを確認する

Google Domainsで送信ができていればCloudflareに移管した後でもそのまま送信することができた。

終わりに

ドメインの移管は初めてて心配だったが調べながら実行していけばそこまで難しくはない。

時間がかかるかもしれない箇所もあるので半日くらいは余裕を持っていた方が良さそう。

参考サイト

Googleカレンダーの予定をGoogleフォームから入力する

バグと戦うエンジニア

イベントの予約などをGoogle Formsでお客さんにしてもらい、その結果をGoogle Calendarに自動で入力する方法。Googleカレンダーをお客さんにも見えるようにすることで埋まっている予定を伝えることもできる。

Googleカレンダーの作成

Googleカレンダーから新しいカレンダーを作成する。

一般の人もアクセスができるようにカレンダーの設定からアクセス許可を一般にする。設定のPublic URLにアクセスすれば誰でもカレンダーを見ることができる。

Googleフォームの作成

Googleフォームで新しいフォームを作成する。日付の項目は必須にしてDate型を選択する。

回答保存時にApps Scriptを使ってカレンダーに登録する

フォームの回答を保存したときにApps Scriptを発火する。Apps Scriptで回答内容を取得し、カレンダーに保存する。

回答保存しにApps Scriptを発火する

フォームの詳細からScript Editorを開く。

適当な関数を用意する。

Apps Scriptの左のメニューからTriggerを追加する。event sourceはFrom form, event typeはOn form submitにする。

定期等な回答を送信して、Apps Scriptのoverviewを見るとイベントが発火していることが確認できる。Executionsからログを確認できる。

permissionエラー

Exception: You do not have permission to call FormApp.getActiveForm. Required permissions:

のようなエラーが出ることがある。Apps Scriptの設定からShow “appsscript.json” manifest file in editorにチェックを入れる。
以下のようにoauthScopesを追記する。

{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/forms.currentonly",
    "https://www.googleapis.com/auth/forms"
  ]
}

Apps Scriptでフォームの回答を受け取る

トリガーする関数でeventを受け取る。以下サンプルコード。

function receiveResponse(e) {
  const itemResponses = e.response.getItemResponses();
  for (const itemResponse of itemResponses) {
    // Logs the items' questions and responses to the console.
    console.log(`Response to the question '${itemResponse.getItem().getTitle()}' was
      '${itemResponse.getResponse()}'`);
  }
}

カレンダーに登録する

eventから必要な情報を抜き出してカレンダーに予定を登録する。以下サンプルコード。

function registCalenderEvent() {
  const calendarId = '****@group.calendar.google.com';
  const myCalendar = CalendarApp.getCalendarById(calendarId);
  let date = new Date();
  const options = {location: '東京', description: '詳細情報'}
  myCalendar.createAllDayEvent('新規イベント', date, options);
}

終わりに

やり方がわかれば2,3時間でサクッと実装できる。他にもいろいろできることがありそう!

参考サイト