joppot

コピペで絶対動く。説明を妥協しない

プログラミング

railsのrakeで作成したカラムの型とdefault値を変更する方法

投稿日:2014年10月13日更新日:

Pocket

hoigerahoigerahio

概要

みなさんこんにちはcandleです。今回はrakeコマンドのややこしいところを扱います。

rakeコマンドはわりと便利で、データベースのカラムの追加や型の変更をマイグレーションファイルから読み込む事で、
複数人でウェブアプリケーションを開発してもデータベースに齟齬が生じない様になっているものです。

一方でrakeコマンドを使うからこそ、柔軟なデータベースの変更が出来ずに苦労することはrailsを使っている人なら一度はあるでしょう。

今回もそのrakeコマンドを使って、カラムの構造を変更します。

前提

railsの実行環境が整っている。



テスト用のモデルを作る

それではテスト用のカラムを作り、そこでrakeコマンドのテストをします。
railsプロジェクトの中で、下のコマンドを実行して、モデルを作成します。
私は例によって、bootstrap3というrailsプロジェクトを使います。

rails g model dbtest name:string description:text

createdbtesttable

下のコマンドでマイグレーションファイルをデータベースに適応させます。

bundle exec rake db:migrate

これでdbtestモデルができました。

データベースを確認する

コマンドラインから、データベースにアクセスします。

rails db

まずはテーブルができているか確認します。
mysqlを使っているなら

show tables;

sqliteなら

.table

です。

checktdbtesttable

ありました。次にカラムの型を確認します。
mysqlなら

DESC dbtests;

sqliteなら

.schem dbtests

です。

checkcolumndbtest

テーブルにレコードを追加する

試しに、railsのコマンドラインからデータを挿入してみましょう。
下のコマンドをrailsプロジェクトの中で実行しましょう。

rails console

aliceさんのデータを作ります。

user1 = Dbtest.new({name: 'alice', description: 'hello'})
user1.save

savealicedata

tomさんのデータを作ります。
tomさんはあえてdescriptionを指定しません。つまりデータベースにnullを入れます。

user2 = Dbtest.new({name: 'tom'})
user2.save

savetomdata

データがデータベースに保存されたか確認します。
データベースにログインして

rails db

下のコマンドを実行します。

SELECT * FROM dbtests;

selecttablesas

いいですね。

これで準備ができました。

カラムの型とデフォルト値を変更する

先ほど、dbtestsテーブルのdescriptionカラムの型は大きいtext型にしましたが、
よくよく考えたら、vachar255のstring型で良い事に気づいたとします。
また、default値を空文字列にします。

descriptionカラムの型を変更しましょう。
下のコマンドでカラム変更の為のmigrationファイルを作成します。

rails g migration ChangeDescriptionOfDbtests

dbtestschangemigrationfile

作成したマイグレーションファイルをエディタで開きます。
始めにdef change 関数を削除します。

deletechangefunc

というのも、def change関数はrake コマンドのrollbackに対応していないからです。
rakeコマンドのrollbackとはデータベースの状態をマイグレーションファイルをもとに過去のデータベース構造に戻すコマンドです。

ところが、def changeで実行されたchange_columnはデータベースの構造を変更する事はできるのですが、それを戻す事はできません。

正直、私はそんなバカな事があるのかと思いましたが、考えてみれば、確かに何を参照して、前のデータベース構造に戻したら良いのかわからないですよね。

ただ、実際テーブルを変更するとなると、また何時戻すとも限らないのでself.up関数とself.down関数を使ってテーブルの型の変更とデフォルト値の設定をします。

def self.up
  change_column :dbtests, :description, :string, :null => false, :default => ""
end

def self.down
  change_column :dbtests, :description, :text,:limit => nil ,:null => true,:default => nil
end

self.up関数では新しいカラム構造を記述します。ここではdescriptionカラムをstring型にして、デフォルト値を空文字列にしています。

self.downでは前のデータベースの構造を記述します。こうすることでrollbackに対応させます。

i89fhaew
(余談ですが、mysqlおよびsqliteのデフォルト値Nullによるrailsのnil判定エラー、例えば.empty?や.present?などを回避したい場合はdefault値で何も無いという文字列 :default => “”を設定すると良いでしょう。)

保存しましょう。
下のコマンドで、データベースに反映させます。

bundle exec rake db:migrate

これで、変更できたと思います。
確認してみましょう。データベースにログインしてスキーマを確認すると

DESC dbtests;

または

.schem dbtests

successchangetype
上手く行きましたね。

まとめ

rakeコマンドのテーブルの変更はなかなか難しいところがありますが、これでやっていけるのではないでしょうか?質問などがあればコメント欄からお願いします。

スポンサードリンク

「為になったなぁ」と思ったら、シェアお願いします。

-プログラミング
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

docker コマンドのショートカットをbash aliasで作成しました

概要 みなさんこんにちはcandleです。今回はdockerコマンドを簡単に操作するためのエイリアスを紹介します。もちろん、僕が便利かなと思って作成したものなので、コピペしてもらい自由により使いやすく …

basscss v8以降にv7以前のスタイルを追加する(自分用メモ)

概要 みなさんこんにちはcandleです。今回はbasscssのv8でかなりデフォルトのスタイルから削除されてしまったスタイルをインポートします。 v7以降からbasscssのスタイルはかなり分割され …

Mysqlテーブルの照合順序を変更する

概要 みなさんこんにちはcandleです。今回はテーブルの照合順序を変更する方法を行います。 この方法はやっても、mysqlクエリー1行ですみます。早速やりましょう。 テーブルの照合順序を変更する 次 …

railsのsimple-captcha gemを使用してform_forを使ったフォームを画像認証する

概要 みなさんこんにちはcandleです。公に開かれたフォームはスパムや総当り攻撃を受けやすいです。 そこで、画像認証を導入して、悪意のあるフォームを拒否してみましょう。 simple-captcha …

wordpressのget_categoriesでサブカテゴリーを含まないカテゴリー一覧を取得する

概要 みなさんこんにちはcandleです。今回はカテゴリー一覧にサブカテゴリーを含まない取得の仕方を紹介します。 サブカテゴリーを使用しているサイトの場合、場合によってはサブカテゴリーとトップの階層の …

  • English
  • 日本語

プロフィール


ベンチャー企業のCTOをやってます。大学時代にプログラミングを始め、javaから入門し、C++へて、PHPへと進み、会社ではRailsを使用。自動化が大好きなプログラマー

スポンサードリンク

アーカイブ