Rails - productionモードでAction Textがロードされない
タイトル通りの問題が起きて調べたのでメモします。
Action Textを導入したrailsアプリをproductionモードで実行したところ、Action Textを用いて実装した箇所がブラウザにロードされない事象が起きました。
解決策
以下のように、config/initializers/asset.rbでプリコンパイルするファイルにscssを追加すると解決しました。
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.precompile += %w( *.scss *.js *application.css)
asset.rbでは、application.js, application.css と他のJS/CSSファイル以外のassetがデフォルトではプリコンパイル対象となるようです。
Action Textはscssファイルを生成するので、これがプリコンパイル対象外になっていたのが原因かと思われます。
マスタリングTCP/IPを読んだ
マスタリングTCP/IP 入門編 第6版 を読みました。
言わずと知れたバイブル的な存在ですよね。実は3年くらい前のIT業界で働き始めの頃に読んでみたことがあるんですが、書いていることのイメージが出来ず読むのが苦痛でしかなかった覚えがあります。あれから3年ほどたった今回は一通り内容を理解できました。エンジニアには想像力が必要と言われますが、当時は想像するにも知識不足からその取っ掛かりがなく挫折に至ったのかなと思います。
なので、”入門”とは書いてるもののある程度の前提知識を要するので、全くの初学者(web, インターネットの知識がないなど)だと読みこなすのは難しいのかなと個人的には思いました。
読んだ感想ですが、とても面白かったです。通信を成り立たせるためのプロトコルの仕様や、パケットの伝送方法などを図解で説明してあり、アプリケーション層のエンジニアが普段意識しないようなネットワークの裏側の動きをよく理解することができました。ただ、分量が多いので、全て暗記するような使い方ではなく、一通り全体像を頭に入れた後に辞書的に参照するのが良さそうです。
忘備録的に、各章の概要だけ簡単にまとめてみます。
第1章 ネットワーク基礎知識
コンピュータネットワークやインターネットが登場するに至った歴史的な背景や、通信を実現するためのOSI参照モデルの概要が書かれています。どんな技術にも言えますが、どのような経緯があって今の仕様になっているのかを知ることは、学習の効率が上がると思うのでこの辺が詳しく書かれているのはよかったです。
第2章 TCP/IP基礎知識
前章で説明されたOSI参照モデルと比較しながら、事実上のその実装であるTCP/IPモデルの概要を解説しています。通信の抽象的なモデルであるOSI参照モデルを、「じゃあ実際どんな風に現実世界で動いているの?」ということ(TCP/IPモデル)と合わせて説明されているのがよかったです。
第3章 データリンク
OSI参照モデルの2層目であるデータリンク層の役割と、実際の挙動を解説しています(イーサネット・ATM・POSなど)。
第4章 IPプロトコル
OSI参照モデルの3層目であるネットワーク層を構成するIP, ICMPなどの仕様、またIPアドレスやパケットの分割/再構築の仕組みについて詳細に解説している。普段業務でpingコマンドなどで間接的にICMPを使ってますが、それが裏でどのような動きをしているのかを詳しく書いてあるのが個人的に面白かったです。
第5章 IPに関する技術
前章の内容をさらに広げ、DNS・DHCP・NATなど外部と通信するために必要な技術・プロトコルの仕様について解説しています。
TCPとUDPについて解説しています。TCPはコネクション型、UDPはコネクションレス型ですが、実際どのようにしてそれらが実現されているのかを詳細に説明しています。
ルーターが特定のIPアドレスにパケットを正しく届けるための仕組み(ルーティング)を解説しています。かなり実践的な内容を含んでいる印象でした。
第8章 アプリケーションプロトコル
OSI参照モデルの最上層であるアプリケーション層でのプロトコル各種(TELNET, SSH, FTP, MIME, SMTP, POPなど)の仕様やWWWについて解説されています。
第9章 セキュリティ
最後はセキュリティについて。ファイアウォールやVPN、それらで用いられる認証・暗号技術について解説されています。
というような感じで、各章構成されています。
DB設計 - スキーマについて
達人に学ぶDB設計を読んだので学んだ内容をまとめます。
DB設計とは?
データベース設計とは、アプリケーションで扱いたい事柄をデータベースで管理できるように、それら事柄を抽象化してデータモデルを作成していく作業です(データモデリング)。
データモデルは「スキーマ(Schema)」という概念から成り、データベース設計というのはこのスキーマを設計することである、と言えます。
それでは、このスキーマとは何でしょうか?
スキーマ
スキーマとは、英単語では「図」「図式」「計画」と言った意味がありますが、データベースにおいても似たような意味で「データ構造」「データのフォーマット」という意味合いで使われます。
このスキーマは、対象となるデータを扱う層によって3つに分けられ、それぞれを
と呼び、総称して3層スキーマと呼びます。
外部スキーマ
外部スキーマとは、Viewから見えるデータ構造を定義するものです。つまり、アプリケーションのUI部分から入出力されるデータについてのスキーマで、ユーザから見えるデータについての定義、とも言えます。
概念スキーマ
概念スキーマとは、開発者から見えるデータ構造を定義するもので、データ同士の関係やデータの要素を定義します。また、テーブルを作成するための設計図(テーブル定義書)になります。この概念スキーマの設計を「論理設計」と呼ぶこともあります。
ちなみに、ここでいう論理とは、常用語での論理の意味とは違い、「物理的制約にとらわれない」と言った意味になります。例えば、DB設計ではサーバのCPUスペックだったりストレージの配置だったり、パフォーマンスや安全性などの面から物理的な事柄を考慮する必要がありますが、それら物理的な要素を排除して考えることを「論理」という言葉で表します。
内部スキーマ
内部スキーマとは、概念スキーマで定義されたデータモデルを具体的にどのようにデータベース(DBMS)内部に格納するかを定義するものです。開発者からは見えませんが、データベースで扱うデータは最終的にはファイルという形で管理されるので、ファイルに関する定義とも言えます。
概念スキーマの論理設計と対比して内部スキーマの設計を「物理設計」とも呼びます。
ここまでで3層スキーマについて書きましたが、図で表すと↓のような感じです。
今回はデータベース設計とは、スキーマとは、ということをまとめました。ここまでお読みいただきありがとうございました。
Vim操作チートシート
随時更新します。
基本的な操作
コマンド 意味 w 次の単語へ e 単語の最後へ b 前の単語の先頭へ 0 行頭へ $ 行末へ gg ファイルの先頭へ G ファイルの最終行へ % マッチした文字へ移動 C-f 次のページへ C-b 前のページへ y ヤンク(コピー) Y 行をヤンク p ペースト P 現在の位置にペースト x カーソル下の一文字を削除 d 削除 D 行内のカーソル以降を削除 dd 行を削除 u 元に戻す C-R 操作を進める r 変更(一文字) R 変更(入力したもの全部) c 一文字消してインサートモードへ C 行内のカーソル以降を削除してインサートモードへ A 行末に移動してインサートモードへ a カーソルの一つ右からインサートモードへ l 行の始まりからインサートモードへ > 右へインデント < 左へインデント gu 小文字へ gU 大文字へ . 事前の操作を繰り返す
その他操作
ファイルの変更箇所確認
:w !diff % -
ターミナルを開く
コマンド 意味 :term 画面上部にターミナルを開く :vert term 垂直分割して開く :bo term 水平分割して下部に開く :top term 水平分割して上部に開く :h vert ヘルプ表示
文字列検索
:vim foo **/*.js | copen
文字列fooをvimが開いているディレクトリ以下を、jsファイルに絞り検索し、copenにより結果を一覧表示。
一括インデント
- ビジュアルモードでインデントしたい行を選択
- ビジュアルモード: shift+v
- 選択: j, kなどでカーソル移動すると選択される
- >を叩く
ハイライト選択解除
:noh
Rails - param is missing or the value is empty: エラー
param is missing or the value is empty:
以下のようなviewとコントローラ(Strong Parameters)を書いていたところ、POST時にparam is missing or the value is empty: article というエラーが発生しました。コードの趣旨としては、articleモデルの属性であるtitle, contentをコントローラにPOSTしたい、といったものです。
view
<%= form_with url: '/admin/articles', local: true do |f| %>
<%= f.label :title, 'タイトル' %>
<%= f.text_field :title %>
<%= f.rich_text_area :content %>
<%= f.submit '投稿する' %>
<% end %>
コントローラ
private
def article_params
params.require(:article).permit(:title, :content)
end
原因と解決策
param is missing or the value is empty: article の内容そのままですが、articleなんていうparamはないよ or 値がないよ、といっています。
今回は前者で、form_withにarticleモデルを関連づけていなかったことが原因でした。なので、以下のようにviewのform_withにarticleモデルを関連づけると解決します。
view
# mode: Article.newを追加
<%= form_with model: Article.new, url: '/admin/articles', local: true do |f| %>
<%= f.label :title, 'タイトル' %>
<%= f.text_field :title %>
<%= f.rich_text_area :content %>
<%= f.submit '投稿する' %>
<% end %>
もしくは、viewを返すコントローラ内で@article = Article.newを追加し、
<%= form_with model: @article, ... %> としても動きます。
Rails - Media Queriesが効かない
問題
Rails on Railsでviewを書いている時に、以下のようにcssをレスポンシブ対応していたのですが、画面を480px以下にしてもスマホ向けのcssが適用されない現象が起きました。
header {
color: white;
}
@media (max-width: 480px) {
header {
color: black;
}
}
解決策
僕の場合は、viewportを設定すれば解決しました。
以下のようにapplication.html.erbのhead内にviewportを記述すると、無事レスポンシブが効くようになります。
...
<head>
...
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
</head>
モダンJavaScript 新仕様(ES2017/2020/2021)
はじめに
ES6以降のモダンなJavaScript仕様について以前こちらの記事にまとめたのですが、個人的に知らなかったシンタックスなどあったので追加でまとめます。
// ES2017から
'7'.padStart(2, 0) // '07'
'7'.padEnd(2, '#') // '7#'
'7'.padEnd(6, 'abc') // '7abcab'
第一引数に結果の文字列の長さ、第二引数に繋げたい文字列(第一引数の数値によって繰り返す)。
// ES2020から
const friends = {
name: 'Tom',
hobby: {
sports: 'soccer',
}
}
friends?.films?.fav // undefined
参照や関数がundefined, nullの可能性であっても接続されたオブジェクトにエラーにならずにアクセスできる。
// ES2020から
null ?? 1 // null
undefined ?? 1 // undefined
false ?? 1 // false
0 ?? 1 // 0
1 ?? null // 1
1 ?? undefined // 1
1 ?? 2 // 2
左辺がnullもしくはundefinedの場合に右辺を返し、左辺がそれ以外なら左辺を返す。OR演算子(||)は左辺がfalsy(null, 0, "", undefined)かどうかを評価する点で異なる。
// これまで
import { Hello } from './module.js'
const module = new Hello()
// ES2020から
import('./module.js')
.then(module => {
const hello = new module.Hello()
})
// 返り値はPromiseなのでasync/awaitも使える
async function main() {
const module = await import('/module.js')
const hello = new module.Hello()
}
モジュールを関数のように呼び出すために導入された。ページの初期表示などでコンテンツが展開するたびにimportを行う(遅延ロード)ことで処理負荷を軽減できる。
// ES2021から
let a = 1
a &&= 2 // 2
a ||= 2 // 1
let b = 0
b &&= 2 // 0
b ||= 2 // 2