Ruby on RailsでタイムゾーンにJSTを使用する方法

やりたいこと

  • タイムゾーンJSTを使用したい。
  • RailsではDB保存はUTCで行い、表示の時だけJSTにするというのが通常の方法らしいが、
    DBの値を元に障害調査する時など表示とDBの値が違うのは何かと面倒であるため、DB保存と表示どちらもJSTにする。

方法

application.rbに設定追加
$ vi config/application.rb
config.time_zone = 'Tokyo'
$ vi config/application.rb
config.active_record.default_timezone = :local

参考サイト

Ruby on RailsでプルダウンメニューをDBの値から作成する方法

やりたいこと

Ruby on RailsでプルダウンメニューをDBの値から生成したい。
各話テーブルのレコードを作成する際に、親となるアニメをプルダウンから選択したい場合など。

方法

collection_selectを使用

Viewのerbファイルにて下記の様に記載

<%= f.collection_select :anime_id, Anime.all, :id, :title %>
  • 第1引数[:anime_id]
  • 第2引数[Anime.all]
    • プルダウンを構成するデータを取得するためのActiveRecordの取得メソッド
  • 第3引数[:id]
    • DBに登録するカラム
  • 第4引数[:title]
    • プルダウンに表示するカラム

参考サイト

Ruby on Railsで外部キー設定

Ruby on Railsで外部キー設定

スムーズに行くかと思いきや、地味にいろいろやることがある。
ちょっとRailsを過信しすぎたかも。

作りたいテーブルのリレーションについて

アニメテーブルの1レコードに各話テーブルの複数レコードが紐付く

やったこと

各モデルクラスおよびテーブル作成
  • アニメモデル作成
$ rails generate scaffold anime title:string anime_image_url:string hash_tag:string
  • 各話モデル作成
$ rails generate scaffold chapter chapter:integer title:string start_time:timestamp end_time:timestamp tweet_collect_start_flg:boolean tweet_collect_end_flg:boolean anime:references
  • マイグレーションファイル確認
    モデル作成コマンドでは「anime:references」と指定しているが、作成されるテーブルのカラムとしては「anime_id」となるので注意。
$ view db/migrate/20130427141102_create_chapters.rb
class CreateChapters < ActiveRecord::Migration
  def change
    create_table :chapters do |t|
      t.integer :chapter
      t.string :title
      t.timestamp :start_time
      t.timestamp :end_time
      t.boolean :tweet_collect_start_flg
      t.boolean :tweet_collect_end_flg
      t.references :anime

      t.timestamps
    end
    add_index :chapters, :anime_id
  end
end
  • モデルクラス確認
    モデル作成コマンドでの「anime:references」により「belongs_to :anime」が自動追加されている。
$ view app/models/chapter.rb
class Chapter < ActiveRecord::Base
  belongs_to :anime
  attr_accessible :chapter, :end_time, :start_time, :title
end
$ rake db:migrate
  • 問題点
    • 特に問題無くテーブルは作成されたが、各話テーブルのanime_idに外部キー制約が付与されていない。
    • 調べたところ「references」はあくまでモデル上のリレーションを設定するもので、DBには反映されないとのこと。
      マイグレーションファイル内にSQLをベタで書くか、プラグインを使用するしか方法はない。今回はプラグインを使ってみた。
外部キー制約補助のためのGem「foreigner」を導入
  • インストール
$ vi Gemfile
gem 'foreigner'
$ sudo bundle install
$ vi db/migrate/20130427141102_create_chapters.rb
class CreateChapters < ActiveRecord::Migration
  def change
    create_table :chapters do |t|
      t.integer :chapter
      t.string :title
      t.timestamp :start_time
      t.timestamp :end_time
      t.boolean :tweet_collect_start_flg, null:false, :default => false
      t.boolean :tweet_collect_end_flg, null:false, :default => false
      # ついでに外部キーにNOT NULL制約を付与
      t.references :anime, null: false
      # 下記行を追加。
      # 「dependent: :delete」により親データが削除された際に子データも自動で削除させる。
      t.foreign_key :animes, dependent: :delete

      t.timestamps
    end
    add_index :chapters, :anime_id
  end
end
$ rake db:migrate:redo
  • 各話テーブルのanime_idに外部キー制約が設定されていることを確認。
その他の要修正ファイルについて
  • Modelクラスについて、scaffold時に「references」を使用したことにより特殊な項目と判断され「anime_id」が追加されてない。
    アプリ動作時に項目が見つからず正常に動作しないため項目を追加
$ vi app/models/chapter.rb
class Chapter < ActiveRecord::Base
  belongs_to :anime
  attr_accessible :chapter, :end_time, :start_time, :title, :anime_id
end
  • Viewのerbファイルについて、本来項目名が「anime_id」であるべきところ「anime」となっている。アプリ動作時に項目が見つからず正常に動作しないため修正
$ vi app/views/chapters/_form.html.erb
  <div class="field">
    <%= f.label :anime_id %><br />
    <%= f.text_field :anime_id %>
  </div>
<% end %>

Ruby on RailsからPostgreSQLを使う

Ruby on RailsからPostgreSQLを使う

RailsもPosgtreSQLも入ったので連携させてみる。

やったこと

DBにPostgreSQLを指定してアプリ作成
  • アプリ作成
$ rails new test_apl -d postgresql
  • Gem関連でエラー発生。Gemのインストールはrootで実施する必要があるので。
$ cd test_apl
$ sudo bundle install
$ cd ../
  • 再度アプリ作成。成功。
$ rails new test_apl -d postgresql
DB設定ファイル編集
$ vi config/database.yml
development:
  adapter: postgresql
  host: localhost
  encoding: utf8
  database: xxxdb_dev
  pool: 5
  username: testuser
  password: testuser
test:
  adapter: postgresql
  host: localhost
  encoding: utf8
  database: xxxdb_test
  pool: 5
  username: testuser
  password: testuser
設定ファイルに従いDB作成
  • DB作成
$ rake db:create RAILS_ENV=development
PG::Error: ERROR:  permission denied to create database
  • database.ymlで設定したユーザにDB作成権限が無かったためエラー発生。ユーザ作り直し。
$ sudo su - postgres
$ createuser -U postgres -P testuser
新しいロールのパスワード:
もう一度入力してください:
新しいロールをスーパーユーザとしますか?  (y/n)n
新しいロールにデータベース作成権限を与えますか? (y/n)y
新しいロールにロールを作成する権限を与えますか? (y/n)n
パスワード:
  • 作成ユーザの権限確認
$ psql -d postgres -U postgres
ユーザ postgres のパスワード:
psql (8.4.13)
"help" でヘルプを表示します.
postgres=# \du
                ロール一覧
 ロール名 |        属性        | メンバー
----------+--------------------+----------
 postgres | スーパーユーザ     | {}
          : ロールを作成できる
          : DBを作成できる
 testuser | DBを作成できる     | {}
  • 改めてDB作成。成功
$ rake db:create

参考サイト

  • 特に無し

さくらVPS上にPostgreSQLインストール その3

さくらVPS上にPostgreSQLインストール

PostgreSQLサーバのリモート接続の設定してみる。

やったこと

postgresql.confの修正
listen_addresses = '*'
port 5432
pg_hba.confの修正
  • 設定のポリシー
    • ローカル接続/外部接続を問わず必ずパスワードによる認証を実施
    • ローカル接続については全ユーザ、全DBへのアクセスを許可
    • 特権ユーザであるpostgresユーザは外部接続を禁止
  • 手順
    • $ sudo su - postgresql
    • $ vi /var/lib/pgsql/data/pg_hba.conf
# 各パラメータの詳細については参考サイトを参照
# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD
local   all                   all                            md5
host    all                   postgres    0.0.0.0/0          reject
host    testdb  testuser     0.0.0.0/0          md5
接続方法見直し
  • 方針
    • ローカル接続/外部接続を問わず必ずパスワードによる認証を実施
    • SSHによるポートフォワードによる接続を行うため、リモート接続はしない
listen_addresses = '0.0.0.0'
  • pg_hba.confを修正
# "local" is for Unix domain socket connections only
local   all         all                               md5
# IPv4 local connections:
host    all         all         127.0.0.1/32          md5

参考サイト

さくらVPS上にPostgreSQLインストール その2

さくらVPS上にPostgreSQLインストール

DB作成することろまで。

やったこと

DB接続用ユーザ作成
$ sudo su - postgres
$ createuser -U postgres -P testuser
新しいロールのパスワード:
もう一度入力してください:
新しいロールをスーパーユーザとしますか?  (y/n)n
新しいロールにデータベース作成権限を与えますか? (y/n)n
新しいロールにロールを作成する権限を与えますか? (y/n)n
  • Uオプション
    • ユーザ作成を行うユーザを指定
  • Pオプション
    • パスワード設定を指定
作成ユーザ確認
$ psql -d postgres -U postgres
postgres=# \du
                ロール一覧
 ロール名 |        属性        | メンバー
----------+--------------------+----------
 postgres | スーパーユーザ     | {}
          : ロールを作成できる
          : DBを作成できる
 testuser |                    | {}
DB作成
$ sudo su - postgres
$ createdb -U postgres -O testuser -W -E UTF8 testdb
  • Uオプション
    • DB作成を行うユーザを指定
  • Oオプション
    • DBの所有者ユーザを指定
  • Wオプション
    • パスワード入力を指定
  • Eオプション
作成DB確認
$ psql -d postgres -U postgres
postgres=# select datname,datcollate,datctype from pg_database;
       datname        | datcollate | datctype 
----------------------+------------+----------
 template1            | C          | C
 template0            | C          | C
 postgres             | C          | C
 testdb               | C          | C
(4 行)

さくらVPS上にPostgreSQLインストール その1

さくらVPS上にPostgreSQLインストール

Rails入れたのでDBも使いたい。PostgreSQL入れてみる。

やったこと

PostgreSQLインストール
$ sudo yum install postgresql-server
$ sudo yum install postgresql-devel
$ sudo yum install postgresql-contrib
システムの文字コードを変更
$ sudo vi /etc/sysconfig/i18n
LANG="ja_JP.UTF-8"
$ sudo reboot
$ env | grep LANG
LANG=ja_JP.UTF-8
DB初期化
$ sudo su - postgres
$ initdb -W -E UTF8 --no-locale -D /var/lib/pgsql/data
  • Wオプション
    • PostgresSQLサーバ内におけるスーパーユーザであるpostgresユーザのパスワードを設定する。
      OS上のユーザのパスワードとは別物なので注意。
  • Eオプション
  • Dオプション
    • データの格納場所を指定。特にオプションで指定しなくても「/var/lib/pgsql/data」が使用される。
PostgreSQL自動起動設定
$ /etc/init.d/postgresql status
postmaster は停止しています
$ chkconfig | grep postgresql
postgresql     	0:off	1:off	2:off	3:off	4:off	5:off	6:off
$ sudo chkconfig postgresql on
$ chkconfig | grep postgresql
postgresql     	0:off	1:off	2:on	3:on	4:on	5:on	6:off
$ sudo /etc/init.d/postgresql start
postgresql サービスを開始中:                               [  OK  ]
クライアントアプリpgadmin3をインストール