Rails初心者のスクラップ
統合テストでdiv.alertの中身がわからない時に中身を見る
assert_select 'div#error_explanation' do |elements|
elements.each do |element|
puts element.text
end
end
chartkickが更新した時とで表示が変わってしまう件
before
<%= javascript_include_tag "chartkick" %>
after
<%= javascript_include_tag "chartkick", defer: true %>
パフォーマンスの測定
@daily_records = DailyRecord.all
# pluck を使った場合の測定
pluck_time = Benchmark.realtime do
@sleep_scores_pluck = @daily_records.pluck(:date, :sleep)
end
# map を使った場合の測定
map_time = Benchmark.realtime do
@sleep_scores_map = @daily_records.map { |record| [record.date, record.sleep] }
end
# 結果を出力
puts "Pluck Time: #{pluck_time} seconds"
puts "Map Time: #{map_time} seconds"
これが速そう
@scores = @daily_records.map do |record|
{
date: record.date,
sleep: record.sleep,
meal: record.meal,
mental: record.mental,
training: record.training,
condition: record.condition
}
end
使うかもしれないリンク
Safari上のinput:dateがcenterになってるのをleftにする
これだとVSCodeで最初の/にニョロニョロが表示される
assert_match /expired/i, response.body
これだとされない
assert_match(/expired/i, response.body)
dom_id ヘルパー
turbo_frame_tag @cat
のようにしてもいいが
turbo_frame_tag dom_id(@cat)
の方が安定&応用が効くっぽい
turbo_frame_tag dom_id(@post, :edit)
とか
参考
エラーいろいろ
ActionView::Template::Error
=> ビューに渡していない変数がテンプレート内で参照されている
chart.jsでツールチップの日付部分の表示を変える
options: {
plugins: {
tooltip: {
callbacks: {
// ツールチップのタイトルを日本式にフォーマット
title: function(tooltipItems) {
if (tooltipItems.length > 0) {
const tooltipItem = tooltipItems[0];
const timestamp = tooltipItem.parsed.x;
const date = new Date(timestamp);
return date.toLocaleDateString('ja-JP', { dateStyle: 'short' });
}
return '';
},
}
}
},
サービスをリリースする
今回使うものたち
- Railsの実行環境:Fly.io
- データベース:TiDB Cloud
- ストレージ:写真とかを扱わなければ不要らしい
わからないこと
Fly.io
$ git push
したら自動的にデプロイされるようにできないの?
TiDB Cloud
- sqlite3とかmysql2とかpostgresqlとか何が違うの?
- ↑これらは開発環境、テスト環境、本番環境でどう使い分けるのがいいの?
- databaseって各環境で個別に作るの?どうやって作るの?
いまやってることとか
参考
本番環境へのあれこれ
本番環境でTLSを使うように修正する
TLS(Transport Layer Security)は、ローカルのサーバーからネットワークにデータを送信する前に大事な情報を暗号化する技術
config.force_ssl = true
本番環境用のWebサーバー
TLSを導入したので、本番環境に適したWebサーバーの設定も必要です。
本番環境ではPumaというHTTPサーバーを使います。Pumaは、大量のリクエストを受信できる能力を備えたサーバーです。
# Pumaの設定ファイル
max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
workers ENV.fetch("WEB_CONCURRENCY") { 4 }
preload_app!
plugin :tmp_restart
RenderのStart Commandの設定
$ bundle exec puma -C config/puma.rb
本番データベースの設定
本番環境のデータベースでPostgreSQLが使われるように設定
GemfileにPostgreSQLのgemを追加する
group :production do
gem "pg", "1.3.5"
end
いつものインストール
$ bundle config set --local without 'production'
$ bundle install
データベースを本番向けに設定する
production:
<<: *default
adapter: postgresql
encoding: unicode
url: <%= ENV['DATABASE_URL'] %>
本番環境用のデータベースを用意する
RenderでPostgreSQLを作成する
Connectionsにある[Internal Database URL]は、後ほどWeb Serviceを作成する際に必要になる
Environment Variableに上記のDATABASE_URL
を追加する
独自ドメインの設定
前提
実行環境はRender
ドメインはお名前.com
Railsの設定
Rails.application.configure do
config.hosts << 'www.example.com'
end
メールの方も設定したけど、こっちはこの後どうなるかわからない
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delivery_method = :smtp
host = 'www.example.com'
config.action_mailer.default_url_options = { host: host }
ActionMailer::Base.smtp_settings = {
:port => 587,
:address => 'smtp.mailgun.org',
:user_name => ENV['MAILGUN_SMTP_LOGIN'],
:password => ENV['MAILGUN_SMTP_PASSWORD'],
:domain => host,
:authentication => :plain,
}
お名前.comの設定
メールサーバー?の設定
メールサービス?はAWS SES(Amazon Simple Email Service)を使用
ドメインはお名前.comを使用
AWSのアカウント作成
- ルートアカウントを作成
- IAMユーザーを作成(おそらくやばいことが起きないように権限を小さくするためのもの)
- DNSレコードをDNSプロパイダーに追加する(お名前.comで設定)
2. IAMユーザーを作成(おそらくやばいことが起きないように権限を小さくするためのもの)
今回許可した権限は以下の2つ
- AmazonSESFullAccess
- CloudWatchLogsFullAccess
3. DNSレコードをDNSプロパイダーに追加する(お名前.comで設定)
お名前.comのDNSレコード設定にCNAMとかMXとかTXTをそれぞれ追加する
お名前.comは気を利かせて「.example.com」を入力しなくてもいいようにしてくれているが
AWS SESの方では「hogehoge.example.com」のようにコピーできるようになっているので
「hogehoge.example.com.example.com」にならないように注意
また、MXは「10 hogehogehoge」のようになっているが、最初の10は優先度の欄に入力するものなので、「10」と「hogehogehoge」で分ける必要がある
参考
エラーを日本語化するにあたって超個人的なつまずきポイント
validates :date, presence: true,
uniqueness: { scope: :user_id, message: "has already been taken" }
なぜか日付の重複だけ英語でエラーメッセージが表示されると思っていたら
雰囲気でつけていたメッセージが邪魔をしていた模様
validates :date, presence: true, uniqueness: { scope: :user_id }
これで解決
エラーの日本語化
Rails は以下の順番で翻訳ファイルを探索して最初に見つかったものを返すらしい(R)
activerecord.errors.models.[model_name].attributes.[attribute_name].key
activerecord.errors.models.[model_name].key
activerecord.errors.messages.key
errors.attributes.[attribute_name].key
errors.messages.key
なんとなくよさそうなエラーメッセージの出し方
<% if object.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
<%= t('errors.template.header',
model: object.class.model_name.human,
count: object.errors.count) %>
</div>
<ul>
<% object.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
参考
パーシャルに変数を渡す
これはエラーになる可能性がある
<% if hoge %>
# hogeが定義されていないとNameErrorが発生
これは安全
<% if local_assigns[:hoge] %>
# hogeが渡されていなければfalseと評価される
フォームの送信先のコントローラーを明示的に宣言
<%= form_with(model: @user, url: password_change_path, method: :patch) do |f| %>
参考
Turboのイベント一覧
↓ こういうの
turbo:load
コードフォーマッターとか
比較項目 | Prettier | RuboCop |
---|---|---|
主な目的 | コードフォーマットの自動統一 | コーディング規約のチェックと修正 |
処理対象 | 構文解析(ASTベース) | 静的解析(抽象構文木とパターン) |
設定方法 | 最小限の設定(opinionated) | 詳細な設定可能(.rubocop.yml) |
修正範囲 | インデント・改行・スペース | 命名規則・メソッド構造・セキュリティ |
自動修正 | 全自動(不可逆的) | 条件付き自動修正(--auto-correct) |
言語対応 | マルチ言語(プラグイン方式) | Ruby専用(拡張で他の言語対応可能) |
perplexityより
debounce
rails stopをする前にコンソールを閉じてしまった場合
$ lsof -i:3000 | grep LISTEN
$ lsof -i:3000 | grep LISTEN | awk '{print $2}' | xargs kill -9
参考URL
語源とか
i18n
i18n(アイエイティーン)は「internationalization(国際化)」の略で、システムをさまざまな言語や地域に適応させることを意味します
i18nは、語頭の「i」と語尾の「n」の間に「internationalization」の18文字があることに由来する数略語です。
a11y
ウェブアクセシビリティ (略語: A11Y、Accessibility の A から Y までの間に 11 文字が挟まれているため、このように略す) は、身体的および技術的な制約によらず、ウェブサイトを使いやすく保つためのベストプラクティスです。
ヌメロニム
ヌメロニム(英語: numeronym)もしくは数略語は、長い英単語を数字で省略して表現する語。比較的長い英単語を、その先頭と末尾のみ残して、間に残された文字をその文字数(桁数)で省略する。代表的な例に i18n など。
Stimulus
targetsはキャメルケースで書く
ハイフンは使用しない、というかハイフンは使用できない
使用するとError invoking action
という呼び出しエラーが発生する
static targets = [];
参考URL