GuideModel » 履歴 » バージョン 10
NAITOH Jun, 2013/04/13 08:31
テーブル削除例追加
1 | 1 | Mitsuyoshi Yoshida | h1. モデルのスケルトンの生成 |
---|---|---|---|
2 | |||
3 | MVC のうち、 Model をまず作っていきましょう。 |
||
4 | プラグインのスケルトン作成と同様にモデルにもスケルトン作成機能があります。 |
||
5 | |||
6 | |||
7 | h2. データベース |
||
8 | |||
9 | モデルはデータベースを扱うものです。ここで簡単にデータベースの説明をしておきます。 |
||
10 | データの一つ一つは *レコード* と呼ばれます。チケットでいうと一つのチケットがレコードになります。 |
||
11 | データの要素は *カラム* と呼びます。チケットでは「題名」、「トラッカー」、「説明」などがそれにあたります。 |
||
12 | このレコードは *テーブル* に格納されます。 |
||
13 | データベースはこのテーブルを複数持ちます。 redmine のデータベースではチケットのテーブル、文書のテーブルといった複数のテーブルを持っています。この redmine のデータベースの中に今回プラグイン用のテーブルを新たに作成することになります。 |
||
14 | |||
15 | |||
16 | h2. モデルの名前とデータ構成を決める |
||
17 | |||
18 | まず、モデルを作成するにはモデルの名前を決めておく必要があります。 |
||
19 | [[GuideSampleSpec|サンプルの仕様]] で決めたデータは特に意味のないサンプル的なものにしました。そこでモデルの名前もよくサンプルで使われる *Foo* とします。 |
||
20 | |||
21 | 次にデータ構成を決める必要があります。すなわちデータがどのようなカラムを持つかということを決めることになります。 |
||
22 | データの要素は *題名* と *説明* にしました。まず、データレコードにはこの 2 つのカラムが必要です。 |
||
23 | これに加えて要素としては *プロジェクト ID* も必要になります。これはプラグインをプロジェクトごとで使用する場合に必要となります。プロジェクトごとのデータというと、ディレクトリのような入れ物の中にデータが格納されるイメージをもたれるかもしれません。しかし、実際には Foo のデータのテーブルは一つで、データの中にどのプロジェクトかという情報をいれたカラムを持たせ、現在のプロジェクトに一致したデータだけを表示するという方法で実現します。 |
||
24 | |||
25 | これらのデータのカラムの名前と型を次のようにします。 |
||
26 | |||
27 | |_. 要素 |_. 名前 |_. 型 | |
||
28 | | プロジェクト ID | project_id | 整数(integer) | |
||
29 | | 題名 | subject | 文字列(string) | |
||
30 | | 説明 | description | 文字列(text) | |
||
31 | |||
32 | 2 | Mitsuyoshi Yoshida | これ以外にも Rails では *id* というカラムを自動的に持ちます。これはデータを識別するための整数型の番号で、データベースにデータを追加する際に自動的に割り振られた番号がこのカラムに入力されます。 |
33 | 1 | Mitsuyoshi Yoshida | これと同様にプロジェクトも id を持っています。これを格納するのが project_id で、データの属するプロジェクトを表します。 |
34 | subject には *string* 、description には *text* の文字列型を使用します。string 型には 256 文字という制限があるため、詳細表示用の description は text にしています。それならば subject も text にすればと思われるかもしれませんが、text は string に比べてデータベースの処理速度が遅くなってしまうため、string で済むものは string にしておいた方がいいでしょう。 |
||
35 | |||
36 | |||
37 | h2. モデルスケルトンの生成 |
||
38 | |||
39 | コントローラのスケルトンの実行コマンドの書式は次のような形です。 |
||
40 | |||
41 | <pre> |
||
42 | 9 | Toshiyuki Ando | $ ruby script/rails generate redmine_plugin_model プラグイン名 モデル名 [カラム名:型 ...] |
43 | 1 | Mitsuyoshi Yoshida | </pre> |
44 | |||
45 | Redmine のトップディレクトリに移動して、決めた名前で実際にコマンドを実行します。 |
||
46 | |||
47 | <pre> |
||
48 | 8 | NAITOH Jun | $ ruby script/rails generate redmine_plugin_model redmine_standard foo project_id:integer subject:string description:text |
49 | 1 | Mitsuyoshi Yoshida | </pre> |
50 | |||
51 | 実行結果 |
||
52 | <pre> |
||
53 | 8 | NAITOH Jun | create plugins/redmine_standard/app/models/foo.rb |
54 | create plugins/redmine_standard/test/unit/foo_test.rb |
||
55 | create plugins/redmine_standard/db/migrate/001_create_foos.rb |
||
56 | 1 | Mitsuyoshi Yoshida | </pre> |
57 | |||
58 | 実行するとモデルの他にテスト用のコードと db/migrate 以下のファイルが作成されます。 |
||
59 | |||
60 | |||
61 | h2. 生成された Migration 用のファイル |
||
62 | |||
63 | データを保存できるようにするにはデータベースにテーブルを作る必要があります。これは Migration と呼ばれる処理で行われ、インストールのときデータベースを作成したように rake で実行されます。 |
||
64 | |||
65 | 8 | NAITOH Jun | このときに使われるのが db/migrate/001_create_foos.rb です。 |
66 | 1 | Mitsuyoshi Yoshida | |
67 | <pre><code class="ruby"> |
||
68 | class CreateFoos < ActiveRecord::Migration |
||
69 | 8 | NAITOH Jun | def change |
70 | 1 | Mitsuyoshi Yoshida | create_table :foos do |t| |
71 | 8 | NAITOH Jun | t.integer :project_id |
72 | t.string :subject |
||
73 | t.text :description |
||
74 | 1 | Mitsuyoshi Yoshida | end |
75 | end |
||
76 | end |
||
77 | </code></pre> |
||
78 | |||
79 | Migration 時にテーブルを作成するメソッドと削除するメソッドがそれぞれ定義されています。 |
||
80 | |||
81 | |||
82 | h2. Migration の実行 |
||
83 | |||
84 | Rails のトップディレクトリで以下のコマンドを実行すると Migration が実行されます。 |
||
85 | |||
86 | <pre> |
||
87 | 8 | NAITOH Jun | $ rake redmine:plugins:migrate |
88 | 1 | Mitsuyoshi Yoshida | </pre> |
89 | |||
90 | 実行結果 |
||
91 | <pre> |
||
92 | 8 | NAITOH Jun | Migrating redmine_standard (Redmine Standard plugin)... |
93 | 1 | Mitsuyoshi Yoshida | == CreateFoos: migrating ===================================================== |
94 | -- create_table(:foos) |
||
95 | 8 | NAITOH Jun | -> 0.0460s |
96 | == CreateFoos: migrated (0.0460s) =========================================== |
||
97 | 1 | Mitsuyoshi Yoshida | </pre> |
98 | |||
99 | 8 | NAITOH Jun | このとき実行されるのは plugins 以下にあるすべてのプラグインです。 |
100 | 各プラグインでは db/migrate 以下にあるファイルを番号の小さいものから順に実行します。生成された Migration 用ファイルの先頭は生成順に番号がふられます。つまり生成した順に実行されることになります。 |
||
101 | 1 | Mitsuyoshi Yoshida | |
102 | この Migration の処理は一度実行したファイルの番号を覚えています。先ほどと同じコマンドをもう一度実行してみてください。 Migration redmine_standard 以下で今度は何もしません。 |
||
103 | |||
104 | プラグイン製作中にデータの構成を変更したくなった場合はもう一度 Model のスケルトンの生成をやり直すか、内容を修正してファイルの番号が大きくなるようにファイル名を変更する必要があります。このとき、すでにテーブルが作成済みの場合エラーとなるので、テーブルも削除しておく必要があります。 |
||
105 | プラグインを公開した後などで、データ構成を変更したくなった場合はカラムの追加、削除といった修正内容を記述した Migration 用ファイルをテーブル作成ファイルよりもファイルの番号が大きくなるようなファイル名で作成します。 |
||
106 | |||
107 | |||
108 | h2. 生成された Model のファイル |
||
109 | |||
110 | Model のファイル app/models/foo.rb を見てみましょう. |
||
111 | |||
112 | <pre><code class="ruby"> |
||
113 | class Foo < ActiveRecord::Base |
||
114 | unloadable |
||
115 | end |
||
116 | </code></pre> |
||
117 | |||
118 | 2 行目に *unloadable* という見慣れないものがあると思いますが、これはおまじないのようなものだと思ってください。ただ、これを書いておかないと development モードで正常に動作しなくなります。 |
||
119 | よく C の入門で使う Hello World のプログラムなどで最初 #include などをおまじないで説明して、後で詳しく説明したりしますが、これはただ書いてあればそれでよいので、おまじないのままでも十分です。詳しく知らないと落ち着かないという方はネットなどで調べてみてください。 |
||
120 | |||
121 | 後はシンプルです。 ActiveRecord モジュールの Base クラスを継承して Foo クラスを定義しているというだけです。Rails の Model クラスでは親クラスの ActiveRecord::Base がほとんどやってくれるので、あまりこちらに記述しなければならない内容はありません。といいつつ実は少し追加する必要があるので、それについては[[GuideNewAction|後で]]説明します。 |
||
122 | |||
123 | Foo クラスの一つのインスタンスが一つのレコード情報に相当します。データの要素にもカラム名のアクセサメソッドでアクセスできます。 インスタンス名を foo とすると foo.subject や foo.description でアクセスできます。データベースからのデータの取得は Foo::find のようなクラスメソッドで行います。 |
||
124 | |||
125 | |||
126 | h2. プラグインのテーブルの削除 |
||
127 | |||
128 | 5 | Mitsuyoshi Yoshida | データのメンバーを変更したいときなど、プラグイン製作中にデータベースのテーブルを削除したくなることがあります。 |
129 | 3 | Mitsuyoshi Yoshida | こういった場合には以下の rake コマンドを実行します。 |
130 | |||
131 | <pre> |
||
132 | 8 | NAITOH Jun | $ rake redmine:plugins:migrate NAME=プラグイン名 VERSION=0 |
133 | 10 | NAITOH Jun | </pre> |
134 | |||
135 | Redmine のトップディレクトリに移動して、決めた名前で実際にコマンドを実行するとテーブル登録済みのデータも含めて削除されます。 |
||
136 | |||
137 | <pre> |
||
138 | 8 | NAITOH Jun | $ rake redmine:plugins:migrate NAME=redmine_standard VERSION=0 |
139 | 3 | Mitsuyoshi Yoshida | </pre> |
140 | |||
141 | 10 | NAITOH Jun | <pre> |
142 | Migrating redmine_standard (Redmine Standard plugin)... |
||
143 | == CreateFoos: reverting ===================================================== |
||
144 | -- drop_table("foos") |
||
145 | -> 0.0013s |
||
146 | == CreateFoos: reverted (0.0014s) ============================================ |
||
147 | </pre> |
||
148 | 3 | Mitsuyoshi Yoshida | |
149 | |||
150 | 6 | Mitsuyoshi Yoshida | h2. sqlite3 によるデータベースの操作 |
151 | 1 | Mitsuyoshi Yoshida | |
152 | 基本的に Rails でデータベースの操作を行う場合、 rake で行いますが、データベースの操作なども少しできると確認などがしやすくなります。 |
||
153 | 8 | NAITOH Jun | 環境は[[GuideDevEnv|開発環境の準備]]のところで用意したとおりのものとして、sqlite3 の場合についても簡単に説明しておきます。操作にはコマンドラインで実行する sqlite3.exe プログラムを使用します。インストールされていない場合はインストールしておいてください。 |
154 | 4 | Mitsuyoshi Yoshida | |
155 | 1 | Mitsuyoshi Yoshida | h3. データベースを開く |
156 | 4 | Mitsuyoshi Yoshida | |
157 | 1 | Mitsuyoshi Yoshida | config/database.yml の設定でデータベースファイルを db/redmine.db としました。まず、このファイルをオープンします。 |
158 | |||
159 | <pre> |
||
160 | 8 | NAITOH Jun | $ sqlite3.exe db/redmine.db |
161 | 1 | Mitsuyoshi Yoshida | </pre> |
162 | |||
163 | 8 | NAITOH Jun | 実行すると *sqlite>* のプロンプトになります。ここで操作用のコマンドを実行します。 |
164 | 1 | Mitsuyoshi Yoshida | |
165 | ヘルプと終了は次のコマンドです。 |
||
166 | |||
167 | <pre> |
||
168 | sqlite> .help |
||
169 | sqlite> .quit |
||
170 | </pre> |
||
171 | |||
172 | h3. テーブルの表示と削除 |
||
173 | |||
174 | 次のコマンドでテーブルの一覧が表示されます。 |
||
175 | |||
176 | <pre> |
||
177 | sqlite> .tables |
||
178 | </pre> |
||
179 | |||
180 | そこで削除したいテーブルを探します。ここでは foos がそれにあたります。 |
||
181 | 8 | NAITOH Jun | そのテーブル名で削除用の SQL 文を実行します。ピリオド(.)で始まっているのは sqlite 用のコマンドですが、テーブルの削除は SQL 文なので、最後に ; が必要です。 |
182 | 1 | Mitsuyoshi Yoshida | |
183 | <pre> |
||
184 | sqlite> drop table foos; |
||
185 | </pre> |
||
186 | |||
187 | |||
188 | 8 | NAITOH Jun | sqlite3.exe でデータベースファイルの後に SQL 文を書くことで、コマンドプロンプトに入らずにテーブルを削除することも出来ます。 |
189 | 1 | Mitsuyoshi Yoshida | |
190 | <pre> |
||
191 | 8 | NAITOH Jun | $ sqlite3.exe db/redmine.db "drop table foos;" |
192 | 1 | Mitsuyoshi Yoshida | </pre> |
193 | |||
194 | |||
195 | 7 | Mitsuyoshi Yoshida | h3. テーブルをもう一度作る |
196 | |||
197 | rake コマンドを使わずにテーブルを消した場合、そのまま migrateion を実行しても先ほど書いたように何もしてくれません。 |
||
198 | この場合は db/migrate のファイルの番号を大きくしてもう一度 rake db:migrate_plugins のコマンドを実行してください。 |
||
199 | |||
200 | 8 | NAITOH Jun | 001_create_foos.rb |
201 | 7 | Mitsuyoshi Yoshida | ↓ |
202 | 8 | NAITOH Jun | 002_create_foos.rb |
203 | 1 | Mitsuyoshi Yoshida | |
204 | 8 | NAITOH Jun | なお、大きくしたファイル番号は元に戻す必要はありません。 |
205 | 1 | Mitsuyoshi Yoshida | |
206 | --- |
||
207 | |||
208 | | [[プラグイン開発ガイド|^]] | [[GuideInitRb|<<]] | [[GuideControlSkelton|>>]] | |