Tips – リストを横並びに

概要

デフォルトのHTML/CSSでは、リスト内の各要素(li)は縦に並べられ、各要素の先頭にマーカーが付される。

このスタイルを変更し、li要素を横に並べるスタイルを設定する。

HTML/CSS

HTML

以下のリストでulタグにクラスを指定し、スタイルを設定する。

CSS

CSSの例は以下のとおり。

冒頭のブロックは関係する要素のリセットCSS。

ulタグに設定したmenuクラスのスタイル

  • list-style-type: noneでリストのマーカー表示を抑止
  • display: flexは、この指定1つで子要素のボックス要素が横並びになる

menuクラスの下のli要素のスタイル

  • 親のulflexを指定しているので、個別要素としてのスタイルを設定
  • liを等幅に設定し、背景色を指定している

Rails/SCSS

HTML

HTMLの内容は同じ。

SCSS

リセットCSSはreset.cssファイルとして切り分けている。

考え方はCSSと変わらず、子要素liをブロック内に入れ子にしている。

 

Tips – アンカーをボタン風に

概要

アンカー要素(a)にスタイルを適用して、ボタンの様な形にする。

HTML/CSS

HTML

HTMLではa要素をdivタグで囲んでクラス定義している。

CSS

CSSの例は以下のとおり。

前段のブロックで関係要素のスタイルをリセットし、bodyの背景色をセットしている。

アンカーのスタイル設定については以下のとおり。

.button_like_anchorクラスの中のa要素のスタイル

  • marginpaddingの設定のためにdisplay: inline-blockを指定
  • box-sizingの設定はここでは影響しないが、サイズ指定してボタンを並べるときなどに関係
  • border-radiusで角を丸くしている
  • text-decoration: nonecolor設定でデフォルトのアンカーの装飾を変更

Hover時の変化

  • 元の背景をbackground-colorで設定
  • 疑似クラスhoverでカーソルが領域に入った時のスタイルを設定
    • 背景色を少し明るくしている
    • cursorでカーソル形状を変更(デフォルトがpointerのため、ここでは影響しない)

Rails/SCSS

html.erb

Railsではアンカータグをヘルパーで実装している。

SCSS

リセットCSSはreset.cssファイルとして切り分けている。

また、疑似クラスhoverの記述をSCSSに合わせて変更している。

 

CSS – リセットCSS

概要

ブラウザーによってデフォルトで設定されているスタイルをリセットしてシンプルにするためのCSS。

リセットに加えて単純のスタイルを設定するものもある。

各種リセットCSS

Eric Meyer’s “Reset CSS” 2.0

HTML5 Doctor CSS Reset

Yahoo! (YUI 3) Reset CSS

 

その他

Normalize.css

A Modern CSS Reset

 

Rails – スタイル設定

概要

Railsのプロジェクトにおけるスタイルシートの場所、スタイル設定について整理する。

デフォルトの状態

プロジェクト生成直後、app/assets/stylesheets/ディレクトリーにapplication.cssが生成され、以下の2行が記述されている。これらの行はディレクティブと呼ばれ、それぞれの意味については後述。

この段階でRailsの”Yay! You’re on Rails!”のページのソースを見ると、HTMLに直接styleタグが書かれている。

コントローラーとスタイルファイルの関係

以下のように2つのアクションを含むコントローラーを3つ生成する(出力は省略)。

その結果、コントローラー・ビューファイルとともに、app/assets/stylesheetsディレクトリーに3つのscssファイルが生成される。

これら3つのscssファイルはコメントのみの空の内容。

ここでorangeビューファイルを表示させてみる。

localhost:3000/fruits/orange

表示されたページのソースのうちスタイルシートの読み込みに関する行を抜き出すと以下のとおり。

以下のことがわかる

  • applicationのほか、新たに生成されたfruits, vesitables, meatsに関するスタイルシートが全て読み込まれる
  • スタイルシートはcss拡張子を持つ
  • ファイル名の本体は、コントローラー名.self-ダイジェストの形式
  • URLクエリーパラメーターを持つ(body=1)
  • スタイルが読み込まれる順番は、application.cssが最後で、その前に他のファイルが辞書順で読み込まれる

これらのファイルは元のscssファイルからcssにコンパイルされた結果で、ファイルの内容のダイジェストが元のファイル名に付加されている。

この場合、application.cssと3つのscss全てのスタイルが適用される。たとえばいずれかのcss/scssファイルに* { color: red; }と記述するとfruits/orangeページの文字の色が赤くなる。

require_selfとapplication.css

無指定でもapplication.cssは読み込まれる

application.cssの以下の2行を削除し、何も指定されていない状態にする。

この状態でorangeページを表示させてソースを見ると、application.cssの読み込みだけ残っている。

require_selfの意味?

application.cssの2行の記述のうち*= require_tree .の行を削除し、ページを表示させてソースを見てみる。

*= require_selfの行に対応してapplication.cssのファイルが読み込まれているが、そもそもなにも指定しなくてもこの行は生成されていた。

次に*= require_selfの方を削除し*= require_tree .を残した結果を見てみる。無指定の時と同じく、ここでもapplication.cssが読み込まれている。

読み込み順の制御は可能

require_treeとrequire_selfの順番を逆にしてみる

そうすると、application.cssが最初に読み込まれるようになった。

ディレクティブ

require_tree

stylesheetsディレクtリーの構成を以下の様に変更する。

  • d:stylesheets
    • f:meats.scss
    • d:crops
      • f:vesitables.scss
      • d:fruits
        • f:fruits.scss

この状態でapplication.cssが初期設定のとき、ページを表示させてもスタイルファイルの読み込みは変わらない。

require_tree .はカレントディレクトリー以下のすべてのディレクトリをたどりながらすべてのファイルをCSSに含める。

次にapplication.cssの内容を以下の様に変更する。

この結果、指定したcropsディレクトリー以下のファイルが再帰的に読み込まれる(application.cssは読み込まれている)。

require_directory

require_directoryは、指定したディレクトリー下のファイルのみをCSSに含める。サブディレクトリー以下は無視される、

この結果は、cropsディレクトリー下のvesitables.cssファイルのみが読み込まれる(application.cssは読み込まれている)。

require ファイル

requireディレクティブにファイル名を指定して、特定のファイルのみを読み込める。

上記の指定で、HTMLファイルにはfruits.cssのみが読み込まれる(application.cssは読み込まれている)。

 

Rails – 基礎的なルーティング

概要

GETやPOSTなどのリクエストがあったときconfig/routes.rbの内容に従って各コードにルーティングされる。

このルーティングファイルの書き方を整理する。

前提

以下のような構成のアプリケーションを考える。

  • コントローラー:pages_controller.rb
    • アクション:top
    • ビュー:top.html.erb
  • コントローラー:users
    • アクション:sign_up、sign_in
    • ビュー:sign_up.html.erb、sign_in.html.erb

デフォルトのroutes.rb

設定と動作

ルーティングファイルはconfig/routes.rbにある。コントローラー生成直後のファイルの内容は以下のとおり。

初期状態では、GETメソッドで各ビューファイルがリクエストされたとき、ディレクトリー構成に従ってファイルを探すようルーティングされる。

たとえばブラウザーでhttp://localhost:3000/pages/topと入力するとpagesディレクトリー下のtop.html.erbが表示される。

このページに他のページからヘルパーでリンクを張る場合は以下の様に書く。

<%= link_to 'トップ', '/pages/top %>

ルーティング

ルーティングの設定状態はrails routesコマンドで確認できる。

Prefixの列はリンクのエイリアスに関する表示で、ヘルパー中でプレフィックスに'_path'を付けた名前でリンク先を表せる。

たとえばtop.html.erb中に以下の行を追加するとリンクが表示され、クリックするとsign_in.html.erbページに遷移する。

<%= link_to('サインイン', users_sign_in_path) %>

まとめ

  • ルーティング設定で各アクションを呼ぶためのURLを設定できる
  • URLでルーティングする場合は文字列とする
  • Prefix_pathを組み合わせたエイリアスでもルーティングができ、その場合はコロンなしで書く

ルーティングの設定変更

設定と動作

コントローラー生成時のルーティングを変更して、それぞれのページがアプリケーションルートから直接呼び出せるようにする(たとえばlocalhost:3000/topなど)。

3つのルーティングとも同じ方法で指定している。

メソッド 'URL', to: 'コントローラー#アクション'

これでそれぞれのURL指定’/top’などに簡略化され、GETリクエストに対して対応するアクションが実行される。

この場合、トップページに以下のようなURL指定のリンクを追加すると、クリック時にサインインページに遷移する。

<%= link_to('サインイン', '/sign_in') %>

ルーティング

ルーティングの一覧は以下のとおりで、Prefixの列も簡略化されている。

Prefixも変更されているので、top.html.erb中に以下の行を追加するとリンクが表示され、クリックするとsign_in.html.erbページに遷移する。

<%= link_to('サインイン', sign_in_path) %>¥

まとめ

  • ルーティングの, to: 'controller#action'によって、設定したURLから指定したアクションにルーティングできる
  • カンマ、toキー(to:)、'コントローラー#アクション'の文字列

ルーティングの名前

設定と動作

routes.rbのsign_inの行に, as:を追加して以下の様に変更する。

get '/sign_in', to: 'users#sign_in', as: :sign_in_page

この場合、リンク先としてsign_in_page_pathを指定してルーティングできるようになる。

ルーティング

このときのルーティングは以下の様になっている。

この場合、linkt_toから呼び出す名前はsign_in_page_pathになり、従前のsign_in_pathを使うとエラーになる。

つまり、as:で指定された内容で元のPrefixがオーバーライドされ、以後はその内容の名前かURLで指定しなければならない。

まとめ

  • ルーティングの名前を', as: :name'で設定できる
  • 設定はカンマ、asキー(as:)、名前シンボル
  • 名前を設定すると、Prefixがそれに置き換えられる

 

Rails – 例題 – コントローラー・ビューを準備する

概要

Railsの例題・掲示板の第1段階のためのコントローラーとビューを生成する。

コントローラー・ビューの生成

プロジェクトディレクトリー下で、2つのコントローラー、pagesusersを生成する。

pagesコントローラーとビュー

生成コマンド

pagesコントローラーには1つのアクションtopを定義する。

rails generate controller pages top

コントローラー

上のコマンドによって、コントローラーファイルpages_controller.rb、ビューファイルtop.html.erbの2つのファイルが生成される。

app/controllers/pages_controller.rb

topアクションに対応する空のメソッドが定義されている。

ビュー

app/views/pages/top.html.erb

コントローラーと同名のディレクトリーがviewsディレクトリーに、アクションと同名のビューファイルがそのディレクトリーにつくられる。ビューファイルにはプレースホルダーの表示が書かれている。

usersコントローラーとビュー

生成コマンド

usersコントローラーには2つのアクションsign_upsign_inを定義する。

コントローラー

上のコマンドの結果、1つのコントローラーファイルusers_controller.rbと2つのビューファイルsign_up.html.erb、sign_in.html.erbが生成される。

app/controllers/users_controller.rb

2つのアクションに対応する空のメソッドが定義されている。

ビュー

コントローラーと同名(users)のディレクトリーがviewsディレクトリーの下につくられ、2つのビューファイルが生成される。

app/views/users/sign_up.html.erb

app/view/users/sign_in.html.erb

ルーティングの設定

基礎的なルーティングに従ってルーティングを設定していく。

デフォルトの設定

コントローラー・ビュー生成後のルーティングはconfig/routes.rbに書かれている。

初期状態では、GETメソッドで各ビューファイルがリクエストされたとき、ディレクトリー構成に従ってファイルを探すようルーティングされる。

たとえばブラウザーでhttp://localhost:3000/pages/topと入力するとpagesディレクトリー下のtop.html.erbが表示される。

ルーティングの設定変更

コントローラー生成時のルーティングを変更する。

  • ビューファイルのディレクトリー構成によらず、URLで/top、/sign_up、/sign_inと指定してアクションが呼ばれるようにする
  • ..._pathのリンク名を定義する

変更後のroutes.rbは以下のとおり。

 

Rails – 例題 – 掲示板

概要

Railsの流れを例題にまとめる。

題材として掲示板を選ぶ。

第1段階

BBSのユーザー登録、サインイン/サインアウト、エラー表示を実装する。

ここでは以下の事項を含む。

  • プロジェクトの開始、主なファイル配置
  • 基礎的なコントロール、ビュー、ルーティング
  • データベースの基本操作
  • フォーム入力、バリデーション、パスワード暗号化
  • モデルによるデータベースの操作
  • セッション管理、アクセス制御

第1段階の内容

第2段階

サインインしたユーザーによる、プロフィールページの閲覧・編集、コメントの投稿・削除、画像ファイルの添付を実装する。

ここでは以下の事項を含む。

  • ユーザーに応じたページの表示・編集
  • リレーションを持つテーブルの設定・操作
  • リソースによる操作
  • 画像ファイルのアップロード

第2段階の内容

 

Rails – form_withとモデルの使い方

概要

form系ヘルパーではフォームの入力がparams変数にセットされるが、一般には以下の様な流れで入力パラメーターを利用する。

  • form_with/form_forで読み込んだパラメーターをモデルにセットする
  • モデルへのパラメーターのセットは、慣習的にprivateのメソッドを準備して、それを介する
  • 各パラメーターは、モデルインスタンスのプロパティーとして参照・利用

モデルによるフォームデータの取得も参照。

例示

基本構造

流れ

  • トップページに入力フォームを表示
    • /top
    • app/controllers/pages_controller#top
    • app/views/pages/top.html.erb
  • フォーム入力をpagesコントローラーのinputアクションへ送信
    • app/controllers/pages_controller#input
  • inputアクションでフォーム入力をUserモデルインスタンスに格納して表示

入力フォーム

form_withによる以下のようなフォームを例にする。フォームビルダーのtext_fieldpassword_fieldに入力された値が送信される。

注意点

form_withはデフォルトでajaxによるフォーム送信となり、ページ全体がレンダリングされない。HTMLとして送信してレンダリングするには、パラメーターにlocal: trueを指定する。

<%= form_with(url:/model: ***, local: true) %>

モデルとデータベース

データを扱うモデルは以下で生成し、マイグレートしてテーブルを作成しておく

テーブル

コントローラー

以下の枠組みでコントローラーを生成。ビューのform_withでモデルを使うため、Userインスタンスを生成している。

ルーティング

  • アプリケーション起動時にtopページを表示
  • 入力POST時にinputアクションへルーティング

入力データのモデルへのセット

コントローラーに以下に様に追記。

要点は次のとおり。

パラメーターを引数にしてモデルインスタンスを与える。

変数 = モデルクラス.new(モデル名_params)

引数はモデルに与えるparamsを返すメソッドで、慣習としてメソッド名の付け方、praivate宣言、requirepremitによるパラメーター取得が定まっている。

params.require(:モデル名).permit(:要素名, ...)

モデルにパラメーターがセットされた後は、要素名と同じモデルのプロパティーで値を取得。

コンソールの出力部分は以下のとおり

require/permitメソッド

フォームの入力をモデルにセットする際、requirepermitでパラメーターを指定している。

たとえば悪意のあるユーザーによってPOSTされる要素が追加された場合でも、必要なパラメーターのみを参照・変更することができる。

そして上述のように、一般的にはrequirepermitのメソッドチェーンをprivateメソッドでラップして使う。

 

Rails – form関係ヘルパーの基本

概要

form系のヘルパーの基本的な機能・挙動について整理してみた。

  • form系の新旧4つのヘルパーの動作についてまとめた
  • モデルを介して複数のパラメーターを扱うform_forform_withのオーソドックスな使い方については、最後の「パラメーターを一括で扱う」にまとめた。

各formヘルパーの関係は

  • form_tagform_forform_withはHTMLのformタグを生成するRailsのヘルパー
  • Rails 5.1より前はform_tagform_for
  • Rails 5.1からform_withが導入され、form_tagform_forは非推奨に

form_tagform_forについては

  • form_tagはブロック内にtext_field_tagなどtag系のヘルパーを持つことを想定
  • データベースと紐づいたモデルを扱う場合はform_for、モデルを介さずにフォームのデータのみやりとりする場合はform_tagを使用

form_withについては

  • form_withform_tagの機能とform_forの機能を1つで使い分け

form_tag

動作

form_tagはフォームブロックの各要素の値を直接ハッシュで取り出すため、モデルは介在しない。

  • form_tagではアクションへのパスを指定し、アクションで各要素の値を参照する
  • 各要素の値は1次元のハッシュparamsに格納されている
  • 要素の値は要素のname属性をキーとして参照

コード間の流れ

app/views/top.html.erb

  • form_tagヘルパーの引数に、POSTを送るアクションへのパスを指定
    • パス指定にはroutes.rbで設定するエイリアスを使っている
  • 各要素ヘルパーの第1引数でid/name属性の値をシンボルで定義

config/routes.rb

  • form_tagからのPOSTを受け取るアクションへのルートを設定
  • URLにエイリアスを使っていて、それをアクションに紐づけている

app/controllers/pages_controller.rb

  • ルーティングの結果呼ばれたアクション内で、フォームの要素から送られた値を処理
  • 要素の値はparams[キーのシンボル]で取り出す

コンソール出力

  • 4行目でPOSTで送られるparams全体が表示されている
  • 6行目でparamsを表示させており、4行目と同じ内容
  • 7~8行目は個別の要素の値をキーを使って参照

form_for

動作

  • form_forでは第1引数にモデルのインスタンスを指定
    • モデルのインスタンスはコントローラーでインスタンス変数として準備
  • form_forでPOSTされた各要素の値はハッシュparams[モデル名のシンボル]に格納される
    • 要素の値を取り出すには以下のハッシュを参照
    • params[モデル名のシンボル][要素名のシンボル]
  • ここでは第2引数のURLでPOST先のアクションを指定している

コード間の流れ

より具体的な実装については、モデルによるフォームデータの取得を参照。

app/views/top.html.erb

  • form_forの第1引数にモデルのインスタンスを指定
    • インスタンスはコントローラーで生成
    • 第2に引数のurl:で指定したパスにPOST
  • form_forの構文は以下のとおり
    • form_for(モデル, オプション群) do |フォームビルダー|
  • 各要素の値はtext_fieldなどフォームビルダーのメソッドで要素名を指定して取得する

config/routes.rb

  • form_tagからのPOSTを受け取るアクションへのルートを設定
  • ここではurl:で指定したエイリアスからアクションに紐づけている

app/controllers/pages_controller.rb

  • ルーティングの結果呼ばれたアクション内で、フォームの要素から送られたデータを確認
  • 各要素の値はparams[モデル名のシンボル]にハッシュとしてまとめられている
  • 個別の要素の値はその中で要素名をキーとしてとりだせる
    • params[モデル名のシンボル][要素名のシンボル]

なお上の例ではform_forの引数に与えるモデルインスタンス(@user)を最初に生成しているが、コントローラーの中ではこれを使わず、ローカルな変数(user)を使っている。

コンソール出力

  • 4行目中、"record" => {"param_text" => "TEXT", ...}が各要素のデータ
  • 6行目に全要素のハッシュ、7~8行目に個別の要素の値が表示されている

form_with (データベースなし)

動作

  • 動作の内容はform_tagと同じ
  • そのためビューにおいてform_withの引数としてURLを指定(url: パス)

注意点

form_withはデフォルトでajaxによるフォーム送信となり、ページ全体がレンダリングされない。HTMLとして送信してレンダリングするには、パラメーターにlocal: trueを指定する。

<%= form_with(url: 'URL', local: true) do |f| %>

コード間の流れ

  • ビューでの書き方以外はform_tagと同じ流れ

app/views/top.html.erb

  • form_withの引数にURLを指定(url: パス)
  • モデルが介在しないform_tagと同じ動作をさせる書き方
  • 各要素はフォームビルダーのメソッドで書いている

config/routes.rb

app/controllers/pages_controller.rb

コンソール出力

form_with (データベースあり)

より具体的な実装については、モデルによるフォームデータの取得を参照。

動作

  • 動作の内容はform_forと同じ
  • そのためにビューにおいて引数にデータベースと紐づいたモデルを指定(model: モデルインスタンス)
  • ここでは第2引数のURLでPOST先のアクションを指定している

<%= form_with(model: 'model', url: 'URL', local: true) do |f| %>

コード間の流れ

app/views/top.html.erb

  • form_withの引数にモデルのインスタンスを指定している
    • model: モデルインスタンス名で指定
    • モデルのインスタンスはコントローラーで生成
  • モデルを介在したform_withと同じ動作をさせる書き方
  • 各要素はフォームビルダーのメソッドで書いている

config/routes.rb

app/controllers/pages_controller.rb

コンソール出力

 

Vagrant/AmazonLinux2 – Railsインストール

概要

VagrantのAmazonLinux2仮想環境rbenv/Rubyをインストール後、Railsをインストールした記録。

  • ホスト:Windows10
  • ゲスト:Vagrant + VirtualBox + bento/amazonlinux-2

Railsの最新版ではなく、オリジナルの環境に併せて特定のバージョンを指定してインストールした。

Railsに影響する機能の停止

SELinux

もともとSELinuxは無効状態だった。

firewalld

そもそもfirewalldはセットされていなかった。

Railsのインストール

一応、gemで使用できるRailsの確認。使用可能なRailsはない。

gemでRailsのバージョン5.1.7を指定してインストール。

再度使用可能なRailsを探して、インストールされていることを確認する。

Railsサーバーの稼働

エラー~JavaScriptランタイムがない

テスト用のプロジェクトを生成してRailsサーバーを起動しようとしたところ、エラーになった。

Node.jsでもよさそうなので、CentOS7と同じ手順Node.jsをインストール。Rails6では最新安定版のNode.jsだと警告が出たのでダウングレード下が、Rails5では最新版では警告が出なかった。

ここまででrails serverの実行が可能になった。

ホストブラウザーからの接続

vagrantfileに以下の1行を記述

config.vm.network "forwarded_port", guest: 3000, host: 3000

テスト用のプロジェクトを生成してrails sを実行すると、「このサイトにアクセスできません」と弾かれる。

netstatで確認すると、ポート3000は開いている。

サーバー立ち上げのオプションを以下の様にして接続成功。

rails s -b 0.0.0.0

以前参考にしたサイトを再度確認すると、Rails4.2以降ではこの接続方法になるとのこと。オリジナルの環境ではrails sで十ていたが(エイリアス?)。

既存プロジェクトの実行

オリジナルの環境でつくったプロジェクトをダウンロードし、共有フォルダー経由で仮想環境に移して実行したところ、db:createでエラーが出た。

指示通りにbundle install

この後db:migrationは問題なく、これでアプリケーションがオリジナルの環境通りに実行できるようになった。

一方、仮想環境で作ったプロジェクトをオリジナルの環境にアップロードした場合、オリジナル側でbundle installが必要になったが、これで問題なく実行できた。