Rails – タイムゾーン

概要

Railsでモデルのデータをデータベースに保存した時、OSやMySQLのタイムゾーンはJSTなのに、created_atupdated_atの時刻がUSTで保存されているのに気付いた。

以下の2つの方法があるようだ。

  • データベースへの登録時刻をJSTにする方法
  • データベースへの時刻登録はUSTとし、表示をJSTにする方法

日本以外でも利用するデータベースの時刻を統一するにはUSTの方がよさそうなので、ここでは2つ目の方法を用いた。

  1. プロジェクトのconf/application.rbに1行追加
    • config.time_zone = ‘Tokyo’
  2. サーバーが実行中の場合は再起動

これでデータベース上はUST、Railsでの扱いはJSTになる。

データベースへの記録はUST

文字列フィールドを1つ持つテスト用のモデルを生成・マイグレートする。

この操作は21時過ぎに実行したが、マイグレーションファイルの時刻が12時台で、9時間遅れているのでUSTとわかる。

なお。CentOSとMySQLのタイムゾーンはTokyoに設定されている。

mysqlにテーブルが作られている。

コントローラーを編集して、トップページ表示時にレコードを保存し、改めて読み込んで表示させる。

データベースへの書き込み時と読み込み時の時刻がUSTになっている。

mysqlで登録されたレコードを確認すると、USTで保存されている。

application.rbでタイムゾーンを設定

プロジェクトのconfig/aplication.rbに以下の1行を追加。

Railsサーバーを立ち上げなおして実行すると、表示がJSTになっている。

 

Rails – formヘルパーとCSRF対策

formヘルパーから生成されるタグ

たとえばfomr_tagヘルパーがレンダリングされると、formタグとhidden属性のinputタグが生成される。

CSRF対策

form系のヘルパーで生成されるhiddenタイプのinputタグは、authenticity_tokenという名前でランダム文字列を値に持つ。

これはフォームに対する送信を確認するもので、Railsから送ったフォーム以外からの送信を排除するための仕掛け。

CSRF(Cross Site Request Forgeries)は、攻撃者のサイトへのリンクをクリックした場合に、そのサイトから意図しない送信が送られてしまうもの。

Railsではformヘルパーで生成されたトークンとサーバー内に持っているトークンが符合すれば、意図したフォームからの投稿と判断される。このためのメソッドがprotect_from_forgery

Rails 5.2より前は、ApplicationControllerprotect_from_forgeryが自動的に記述される。

Rails 5.2以降はActionController::Baseで有効になっていて、追加記述の必要はない。

 

Rails – モデルによるDB操作の仕組み

概要

モデルによるデータベース操作を、できるだけ基本的な方法で行うことを試した。

またテーブル構造の変更に対して、マイグレーションを行わずにmysqlコンソールとコントロールファイル編集だけで対応できることを確認した。

モデルとテーブルの生成

モデルの生成

以下の様にモデルを生成する。このモデルは文字列型のフィールドを1つ持っている。

rails generate model record col1:string

app/models/record.rbが作成される。

マイグレーションファイルも作成されていて、string型のフィールドが定義されている。

マイグレーション~テーブル生成

このモデルからマイグレーションによりテーブルを生成する。

rails db:migrate

mysqlでテーブルが生成されていることと、そのテーブルの構造が確認できる。

モデルの構造の確認

コントローラーからモデルの内容を出力させる。

トップページを出力させると、サーバー実行中のコンソールに以下が出力される。

Railsデフォルトのid、created_at、updated_atに加えてcol1が要素に加わっている。

データの登録確認

トップページアクセス時にレコードを1つ登録する。レコードのフィールドはハッシュで指定する。

Railsサーバーのコンソールに以下が出力され、データが生成・登録されていることがわかる。

mysqlでもテーブルへの登録状況が確認できる。

データの読み込み確認

トップページ読み込み時にデータベースを読み込んで表示するように変更する。

出力は以下のとおりで、データベースの内容が読みだされている。

MySQLでのテーブル変更

以下の様にmysqlで直接テーブルにフィールドを加える。

Railsで変更後テーブルへの書き込み

トップページアクセス時に、フィールド追加後のテーブルに新たなデータを書き込むように変更。

トップページ表示時にデータが登録され、テーブルは以下の様に更新されている。

 

Rails – プロジェクトでのデータベース準備

概要

Railsでモデルによりフォームやデータベースとのやり取りをする流れ。

  1. プロジェクト生成時にDBMSを指定
  2. database.ymlを編集してデータベースを生成
  3. モデルを生成
  4. マイグレーションでテーブルを生成
  5. モデルでフォームデータを取得
  6. モデルでテーブルを読み書き

プロジェクト生成時

プロジェクト生成時にDBMSを指定する。

  • Rails2.0.2以降ではデフォルトデータベースがMySQLからSQLiteに変更
  • MySQLを使う場合、プロジェクト生成時に以下の様に指定

rails generate project_name -d mysql
rails generrate project_name --database=mysql

データベースの生成・操作

database.ymlの編集

config/database.ymlファイルの内容を設定・変更

データベースの生成

以下のコマンドでdatabase.ymlの設定に従ってデータベースを生成。

rails db:create

データベースの確認

以下のいずれかの方法で、アプリケーションのデータベースを確認できる。

  • mysql -u user -pを実行してMySQLのコンソールに入る
  • プロジェクトディレクトリー内でrails dbconsoleを実行して、アプリケーションが使うデータベースをuseした状態でMySQLのコンソールに入る

データベースの削除

以下のコマンドでアプリケーションで使っているデータベースが削除される。有無を言わさずすべてのテーブルごと消えてしまうので注意。

rails db:drop

実行例

database.yml

データベース名を設定する。以下はdemo_appアプリケーションでdemo_app_dbを使う設定。

データベースの生成

rails db:createコマンドでdatabase.ymlの設定を使ってデータベースを作成する。

rails dbconsoleコマンドでデータベースが作成されたことを確認。

Rails – ヘルパーメソッド

主なヘルパーメソッド

link_to

<a>要素を生成する。

基本形

<%= link_to "表示テキスト", URL %>

  • <a href=URL>表示テキスト</a>を生成
  • URLは文字列形式のほか、routes.rbas:指定をしたパス(***_path)を指定可能

属性の追加

<%= link_to text, URL, :attr_name => 'attr_value' %>

  • たとえばid属性の場合、:id => 'ID'など
  • 複数の属性をカンマで区切って列挙できる

フォーム関係

Rails – DB操作~基礎的な読み書き

概要

  • Railsでデータベースを操作する場合、フォームの入力~モデル~データベースを自動で関連付ける方法が一般的
  • ここでは、モデルオブジェクトを直接操作してデータベースとの間での書き込み・読み込み処理を整理する

手順

書き込み

手順は以下の通り。

  1. カラム=プロパティーを指定してモデルインスタンスを生成
    • @model_name = ModelName.new(col1: val1, ...)
  2. インスタンスメソッドsaveでデータベースに書き込み
    • @model_name.save
  3. 結果として返されるtrue/falseに応じて必要な処理を行う

読み込み

全データを読み出す場合、モデルクラスのクラスメソッドallを使う。

  • @model_names = ModelName.all

この変数をviewなどで利用するときは、各フィールドをプロパティーとして参照する。

  • @model_names.col1

 

Rails – 基礎的なフォーム

概要

フォームとのパラメーターのやりとりのみを確認する。

  • 既存のビューにフォーム関係のタグを書き、新たなアクションに送信する
  • 既存のコントローラーにそのアクションを追加し、フォームからのデータをパラメータとして受け取る
  • 受け取ったパラメーターをフォームを書いた既存のビューに渡してレンダリング
  • フォーム関連のタグをヘルパーに置き換える

元になる枠組み

  • プロジェクト:demo_app
  • コントローラー:demo_contents
  • アクション:top_page
  • ビュー:top_page.html.erb

STEP-1~form_tag

ビューファイルへのフォームの記述

top_page.html.erbに以下の内容を記述。

上記のform_tagは、submitされた内容を指定したアクションにpostするformタグを生成する。

ただし直接formタグを書くと”invalid authenticity token”エラーになる。

コントローラーにアクション追加

フォームからPOSTで送られる内容を受けるアクションを、コントローラにメソッドとして追加する。

ルーティングの追加

config/routes.rbファイルに、POSTに対するアクションメソッドへのルーティングを追加する。

アクションの確認

ルートページにフォームが表示され、テキストボックスにメモを入力して送信ボタンを押すと、Railsサーバーにデータが送られている様子が表示される。

STEP-2~params

params変数の確認

  • フォームからsubmitされたときのフォーム要素の値は、params変数に格納される
  • params変数はハッシュで、フォーム要素のname属性で指定した内容がキーになる

確認のため、demo_contentsコントローラーのpost_memoアクションに1行追加する。

ここでテキストボックスにメモを入力して送信すると、Railsサーバーにその内容が表示される。

params変数のHTMLへの反映

上記のpost_memoアクションの内容を以下の様に変更する。

  • viewから参照可能な@memoにフォームから受け取ったparams[:memo]の内容をセット
  • トップページへのレンダリングとreturn

@変数はクラスのインスタンス変数で、これをアクションとビューで共有できる。

またビューファイルtop_page.html.erbに以下の様に追記する。コントローラーでセットされた@memoの内容をHTMLで表示させている。

この結果、送信ボタンを押すと入力したメモの内容がtop_pageに表示されるようになる。

STEP-3~フォームヘルパー

フォーム内の要素を、以下の様にフォームヘルパー関数に書き換える。

さらにformヘルパーはhiddenタイプのinputタグを追加するが、これはCSRF対策のため

上記のlabel_tagtext_field_tagsubmit_tagはそれぞれ対応するタグに変換される~フォームヘルパー(旧)

form_tagヘルパーのまとめ

フォーム全体

  • form_tag…endヘルパーでフォーム全体を囲む
  • form_tagではポスト先のURLを指定する
  • ポスト先のURLはroutes.rbでポスト先アクションにルーティングしておく

フォーム内のヘルパー

  • label、inputタグに置き換えられるヘルパーの多くは、第1引数にname属性に対応する引数をとる
  • この名前引数には、一般にシンボルがあてられる

受信側での扱い

  • 受信側ではparamsというハッシュにフォームからの受信結果が入れられる
  • 受信のためにルーティングされたアクション内で、このparamsを参照する
  • paramsのキーに、フォームでname属性に指定したシンボルを使って値を読み出す

 

Rails – フォームヘルパー(旧)

共通事項

名前の指定

タグのid/nameやラベルのforに指定する識別子の指定方法に、文字列とシンボルの2種類がある。

text_field_tag(:name)
text_field_tag("name")

いずれも生成されるタグはid/nameに文字列が設定される。

<input type="text" id="name" name="name">

基本系

form_tag

form_tagfomタグを生成する(Railsdoc)。

form_tag(action [option/HTML_attr/event]) do
end

アクションを指定

メソッドを指定

multipart指定

 

submit_tag

submit_taginputタグのtype="submit"を生成する(Railsdoc)。

submit_tag([button_name , option/HTML_attr/event])

ボタン名を指定:第1引数はボタン名

無効化

POST中の表示の指定

label_tag

label_tagはフォーム要素と関連付けられたラベルタグを生成する(Railsdoc)。

label_tag(id&name [, contents [, HTML_attr or event])

識別子と内容を指定

テキスト入力系

text_field_tag

text_field_taginputタグのtype="text"を生成する(Railsdoc)。

text_field_tag(id&name [, value, option/HTML_attr/event])

識別子のみ指定:第1引数がidとnameにセットされる

値を指定:第2引数がvalueの値になる

識別子とプレースホルダーを指定

クラス指定

 

Rails – ルーティング

ルーティングファイルの役割

RailsがユーザーのブラウザーからGETやPOSTなどのリクエストを受け取ると、まずルーティングファイルを参照する。

ルーティングファイルには、リクエストの種類、リクエストのターゲットURL、ターゲットURLに対応するコントローラーとアクションが記述されている。

その内容に従って必要なコントローラーが呼び出されて処理を行った後、ユーザー側へレンダリングされた内容が返される。

ファイルの位置とファイル名

ルーティングファイル(routes.rb)は、プロジェクト生成時にconfigディレクトリー下に生成される。

config/routes.rb

ファイルの内容

アクションを指定してコントローラーを生成すると、routes.rbにそのアクションへのルーティングを記述した1行が追加される。

たとえばコントローラーとしてdemo_contents、そのアクションとしてtop_pageを指定して生成すると以下のような内容でルーティングの記述が追加される。

一方、アクションを指定せずにコントローラーだけ指定して生成すると、route.rbへの追加は行われない。

基本的なルーティングの書き方

URL指定

以下の3つの記述は全て等価で、ブラウザーからURLをlocalhost:3000/demo_contents/top_pageと指定してGETリクエストしたとき、demo_contentsコントローラーのtop_pageアクションが実行される。

2つ目と3つ目の記述法では、URLに他の表現を設定することが可能。

以下の例ではlocalhost:3000/fooを指定した時に、demo_contentsコントローラーのtop_pageアクションが実行される。

ルートページの指定

ルートページとして特定のコントローラー・アクションを設定するときは、以下の様に記述する。

項設定すると、localhost:3000のようにブラウザーからリクエストするとdemo_contentstop_pageアクションが実行される。

基礎的なルーティング

rails routesによるルーティングの確認、to:によるURLの置き換え、as:による名前付けなどの基礎的な事項は以下にまとめた。

基礎的なルーティング

RESTful

今後

 

Rails – コントローラー/ビュー~ページの作成

概要

プロジェクト生成直後などに、コントローラーとアクションを生成してページをつくり、確認する。

生成時

  • コントローラーファイルが生成される
  • アクションに対してビューファイルが生成される
  • リクエストに対するコントローラーとアクションのルーティングが定義される

実行時

  • ユーザー側のブラウザー/クライアントからGETなどのリクエストでページが要求される
  • リクエストはプロジェクトのroutes.rbファイルの内容に従ってコントローラークラスのアクションメソッドに送られる
  • アクションメソッドは必要な内容を実行し、ビューファイルをレンダリング
  • レンダリングされたページがコントローラーを介してクライアントに送られる

手順

ディレクトリーの移動

プロジェクトディレクトリーに移動する。

cd project_name

コントローラーとアクションの生成

以下のコマンドでコンローラーを作成する。アクションを指定しない時はaction_nameを省略してもよい。

rails generate controller controller_name action_name 

プロジェクトディレクトリー下に以下のファイルが作成される。

  • app/controllers/controller_name_controller.rb
  • app/views/controller_name/action_name.html.erb
  • app/assets/stylesheets/controller_name.scss

コントローラーファイル

ファイルの位置とファイル名

app/controllers下のファイルにコントローラーのクラスが定義される。

クラスファイル名はスネークケース末尾に'_controller'がつけられる。拡張子は.rb

  • controller_name_controller.rb

ファイルの内容

ファイル内容はクラス定義で、コントローラーとアクションを指定して生成した場合、以下が定義されている。

  • コントローラークラス
    • コントローラークラスはApplicationControllerクラスを継承
    • クラス名はパスカルケースで、末尾に'_Controller'がつけられる
      • ControllerNameController
  • アクションメソッド
    • コントローラークラスのメソッドとして定義される
    • アクション名はスネークケース
      • action_name

後からアクションを追加する場合、コントロールクラスのメソッドとして追加し、ルーティングを設定する。

ビューファイル

ファイルの位置とファイル名

app/viewsディレクトリーの下にコントローラー名と同じフォルダーが作成され、その下にアクション名と同じ名前のスネークケースでアクションメソッドが定義される。拡張子は.html.erb

app/views/demo_contents/top_page.html.erb

ファイルの内容

コントローラー追加直後のビューファイルの内容はシンプルで、コントローラー#ビューの表示がH1要素で、その場所がp要素で書かれている。

後からアクションを追加する場合、アクション名と同じファイル名でhtml.erbファイルを作成し、その内容にHTMLを書いていく。

スタイルシート

ファイルの位置とファイル名

コントローラーを生成すると、アプリケーション固有のスタイルシートがapp/assets/stylesheetsにつくられる。ファイル名はコントローラーと同じスネークケースで拡張子は.scss

app/assets/stylesheets/controller_name.scss

拡張子からわかるように、スタイルシートはSCSSで書くことを想定している。

ファイルの内容

ファイルの内容はコメントのみで、ゼロからスタイルを指定するようになっている。

参照:Railsにおけるスタイルシートの設定

ルーティングファイル

ファイルの位置とファイル名

ルーティングファイルはconfigディレクトリー下のroutes.rbファイル。

config/routes.rb

ファイルの内容

コントローラーが生成されるのに合わせて、routes.rbに1行追加される。

この場合、ブラウザー側からは以下のURLでアクセスするとアクションメソッドで指定したページが表示される。

localhost:3000/controller_name/action_name

参照:Railsにおけるルーティング基礎的なルーティング

確認

ここでプロジェクトディレクトリー下でRailsサーバーを立ち上げる

rails s -b 0.0.0.0

その後ホストのブラウザーで以下のURLを直に入力すると、シンプルなページが表示される。

localhost:3000/controller_name/action_name

ページの削除

コントローラーの削除は以下のコマンドで実行。

rails destroy controller controller_name

このコマンドでコントローラーファイルやビューファイルなどはきれいに削除されるが、routes.rbの記述だけは残るため別途削除する必要がある。

実行例

コントローラーとアクションの生成

demo_appというプロジェクトを作成した後、demo_contentsというコントローラーとその下のtop_pageというアクションを定義する。

コントローラーファイル

ファイルの位置と名前

app/controllersディレクトリーの下に以下のファイルが生成される。

demo_contents_controller.rb

ファイル名はスネークケースで、コントローラー名の後ろに_controllersが付加される。拡張子は.rb

ファイルの内容

パスカルケースでコントローラークラスの空の定義が生成される。この場合はdemo_contentsからDemoContentsControllerクラスが定義され、メソッド名はスネークケースでtop_pageとなっている。

ビューファイル

新たに作成されたapp/views/demo_contentsディレクトリーに、アクションに対応したビューファイルが生成されている。

この場合、ディレクトリー名がコントローラー名demo_contents、ビューファイル名がアクション名に基づいてtest_page.html.erbとなっている。

ファイルの内容はシンプルなHTML。

  • H1要素でコントローラークラス名とアクション名(DemoContents#top_page)を表示
  • p要素でビューファイルのパスを表示(app/views/demo_contents/top_page.html.erb)

スタイルシート

app/assets/stylesheets/に作成されたスタイルシート(demo_contents.scss)の内容を確認してみる。コメントのみの空の内容なのが確認できる。

ルーティングファイル

config/routes.rbを確認すると1行追加されている。

 

以下のURLでアクションで設定されたページが表示される。

localhost:3000/demo_contents/top_page

表示結果は以下のとおりシンプル。