GuideConclusion » 履歴 » バージョン 6
NAITOH Jun, 2013/04/14 21:33
RESTfulな実装に変更。
1 | 1 | Mitsuyoshi Yoshida | h1. まとめ |
---|---|---|---|
2 | |||
3 | プラグインの作り方のまとめです。 |
||
4 | |||
5 | h2. Rails |
||
6 | |||
7 | Rails のポイントは MVC 構造と 2 つの方針です。 |
||
8 | |||
9 | h3. MVC 構造 |
||
10 | |||
11 | |_. Model | データを扱う部分。クラスのインスタンスがデータベースの 1 つのレコードに対応し、テーブルからの取得にはクラスメソッドを使用する | |
||
12 | |_. View | html を作成する部分。 Erb で埋め込み式の ruby コードを評価して作成する | |
||
13 | |_. Control | ユーザのアクションに応答する部分。アクションに対応したメソッドを実行する | |
||
14 | |||
15 | |||
16 | |||
17 | h3. 設定よりも規約 |
||
18 | |||
19 | 名前に規則を持たせることで設定の手間を省き、簡単に作成できるようにします。 |
||
20 | |||
21 | ファイルを置くディレクトリは決まっています。 |
||
22 | |||
23 | |||
24 | *プラグインのディレクトリ* |
||
25 | |||
26 | <pre> |
||
27 | 5 | NAITOH Jun | (Redmine のトップディレクトリ)/plugins/(プラグイン名) |
28 | 1 | Mitsuyoshi Yoshida | </pre> |
29 | |||
30 | *プラグインディレクトリ内* |
||
31 | |||
32 | <pre> |
||
33 | init.rb 最初にロードされるファイル。プラグインの定義を記述 |
||
34 | app/ |
||
35 | ├ controllers/ コントローラ |
||
36 | ├ models/ モデル |
||
37 | └ views/ ビュー |
||
38 | db/migrate/ データベース操作 |
||
39 | config/locales/ 国際化用メッセージファイルの格納 |
||
40 | </pre> |
||
41 | |||
42 | |||
43 | ファイルは基本的に 1 ファイルに 1 クラスを記述し、ファイル名はクラス名をスネークケースに変換した名前になります。 |
||
44 | |||
45 | <pre> |
||
46 | FoosController -> foos_controller.rb |
||
47 | </pre> |
||
48 | |||
49 | ビューのファイルは 1 ファイルに 1 つのアクション用ページを記述します。 |
||
50 | |||
51 | <pre> |
||
52 | app/views/(コントローラ名)/(アクション名).html.erb |
||
53 | |||
54 | ex.) app/views/foos/index.html.erb |
||
55 | </pre> |
||
56 | |||
57 | |||
58 | |||
59 | h3. 繰り返しの禁止 |
||
60 | |||
61 | 同じことを何度も書かない。 |
||
62 | |||
63 | 繰り返しを避けるための機能が用意されています。 |
||
64 | |||
65 | *before_filter* |
||
66 | |||
67 | コントローラで各アクションのメソッドの前に実行されるメソッドを指定します。 |
||
68 | |||
69 | *部分描画* |
||
70 | |||
71 | ビューで同じ部分を別ファイルとして共通化します。 |
||
72 | 部分描画用のファイル名には先頭に _ を付けます。指定する場合は _ と拡張子を省き、 app/views からのパスを書きます。 |
||
73 | |||
74 | 6 | NAITOH Jun | <pre><code class="erb"> |
75 | 1 | Mitsuyoshi Yoshida | <%= render :partial=>"foos/form" %> |
76 | </code></pre> |
||
77 | |||
78 | |||
79 | *レイアウト* |
||
80 | |||
81 | 全ビューで共通する部分はレイアウトファイルに書きます。 |
||
82 | レイアウトファイルは app/views/layouts 以下に置き、コントローラでレイアウトを指定します。 |
||
83 | |||
84 | <pre><code class="ruby"> |
||
85 | layout "standard" |
||
86 | </code></pre> |
||
87 | |||
88 | |||
89 | h2. スケルトンの生成 |
||
90 | |||
91 | プラグインを作るには雛形となるスケルトンを作成して、そこに中身を追加していきます。 |
||
92 | スケルトンは *プラグイン全体* 、 *コントロール* 、 *モデル* の 3 つです。 ビューはコントロールと一緒に生成されます。 |
||
93 | |||
94 | プラグインの作成は Rails のトップディレクトリで実行します。 |
||
95 | |||
96 | <pre> |
||
97 | 5 | NAITOH Jun | $ ruby script/rails redmine_plugin プラグイン名 |
98 | $ ruby script/rails redmine_plugin_controler プラグイン名 コントローラ名 [アクション名 ...] |
||
99 | $ ruby script/rails redmine_plugin_model プラグイン名 モデル名 [カラム名:型 ...] |
||
100 | 1 | Mitsuyoshi Yoshida | </pre> |
101 | |||
102 | モデルの場合にはデータベースへのテーブル作成用のファイルも生成されます。 |
||
103 | テーブルの作成には rake を使用します。 |
||
104 | |||
105 | <pre> |
||
106 | 5 | NAITOH Jun | $ rake redmine:plugins:migrate |
107 | 1 | Mitsuyoshi Yoshida | </pre> |
108 | |||
109 | |||
110 | スケルトン生成後、次のような作業を行うことになります。 |
||
111 | |||
112 | *init.rb* |
||
113 | |||
114 | * バージョンなどの各情報を設定します。 |
||
115 | * プラグインのトップページを呼び出すためのメニューを追加します。 |
||
116 | |||
117 | *モデル* |
||
118 | |||
119 | * データ要素が妥当なものかの判定処理を追加します。 |
||
120 | |||
121 | *コントロール* |
||
122 | |||
123 | * 各アクションごとのメソッドを実装します。 |
||
124 | |||
125 | *ビュー* |
||
126 | |||
127 | * 各アクションごとのページの内容を記述します。 |
||
128 | |||
129 | |||
130 | |||
131 | h2. プロジェクトごとのプラグイン |
||
132 | |||
133 | プロジェクトごとにデータ管理するプラグインにするために必要なことをあげます。 |
||
134 | |||
135 | * init.rb |
||
136 | ** プロジェクトモジュールの登録 project_module |
||
137 | *** 各アクションの権限の指定 permission |
||
138 | ** プロジェクトメニューへの項目の追加 menu |
||
139 | * コントローラクラス |
||
140 | ** @project の設定 Project.find(params[:id]) |
||
141 | ** ログインチェック authorize |
||
142 | ** メニューを選択状態 menu_item |
||
143 | |||
144 | |||
145 | h2. 国際化 |
||
146 | |||
147 | config/locals 以下に言語別のメッセージファイル(en.yml, ja.yml など)を作成します。 |
||
148 | メッセージファイルには、キーとメッセージのペアを記述します。 |
||
149 | |||
150 | <pre><code class="yaml"> |
||
151 | 言語の識別子: |
||
152 | シンボル名: メッセージ |
||
153 | シンボル名: メッセージ |
||
154 | # : |
||
155 | </code></pre> |
||
156 | |||
157 | メッセージファイルの記述には注意事項があります。 |
||
158 | |||
159 | * インデントで階層化される |
||
160 | * タブの使用禁止 |
||
161 | * 文字コードは UTF-8 |
||
162 | |||
163 | |||
164 | 通常、メッセージを取得する場合には次の国際化ライブラリ(i18n)のメソッドを使用します。 |
||
165 | |||
166 | <pre><code class="ruby"> |
||
167 | l(:キー) |
||
168 | </code></pre> |
||
169 | |||
170 | |||
171 | しかし、以下のものは自動的にキーが検索されます。あえてラベルを変えたい場合はオプションで :label の値を指定します。 |
||
172 | |||
173 | |_. 項目 |_. 検索キー |_. 例 | |
||
174 | | メニュー項目 | label_項目名 | label_standard | |
||
175 | | モジュール名 | project_module_モジュール名 | project_module_standard | |
||
176 | | 権限項目 | permission_名前 | permission_view_foos | |
||
177 | | フォームのフィールド | field_フィールド名 |field_subject | |
||
178 | |||
179 | |||
180 | h2. データの流れ |
||
181 | |||
182 | h3. ビュー → コントロール |
||
183 | |||
184 | メニューやビューの link_to などで作ったリンクまたはフォームからコントロールのアクションが呼び出されます。 |
||
185 | |||
186 | 6 | NAITOH Jun | リンクはハッシュで指定する場合、 :control, :action などの要素でアドレス(呼び出すアクション)を指定し、後のパラメータは *params* 変数にハッシュとして格納されてコントロールに渡されます。 プロジェクトの識別名は project_id をキーとして指定します。:id パラメータは特殊でアドレスの一部としても使われます。 |
187 | 1 | Mitsuyoshi Yoshida | |
188 | <pre><code class="ruby"> |
||
189 | 6 | NAITOH Jun | link_to 表示文字列, {:control=>:foos, :action=> :show, :project_id => "demo", :id => 1} |
190 | 1 | Mitsuyoshi Yoshida | </code></pre> |
191 | |||
192 | 6 | NAITOH Jun | このリンクをルーティングで設定したパスで指定すると簡潔で理解しやすくなります。 |
193 | 1 | Mitsuyoshi Yoshida | <pre><code class="ruby"> |
194 | 6 | NAITOH Jun | link_to 表示文字列, project_foo_path("demo", 1) |
195 | </code></pre> |
||
196 | |||
197 | アドレスのルーティングは下記のように config/routes.rb で URL を設定する必要があります。 |
||
198 | <pre><code class="ruby"> |
||
199 | 1 | Mitsuyoshi Yoshida | Rails.application.routes.draw do |
200 | 6 | NAITOH Jun | resources :projects do |
201 | resources :foos do |
||
202 | post 'preview', :on => :collection |
||
203 | put 'preview', :on => :member |
||
204 | end |
||
205 | end |
||
206 | 1 | Mitsuyoshi Yoshida | end |
207 | </code></pre> |
||
208 | |||
209 | 6 | NAITOH Jun | ルーティングは *rake routes* で確認します。 |
210 | <pre> |
||
211 | project_foos GET /projects/:project_id/foos(.:format) foos#index |
||
212 | POST /projects/:project_id/foos(.:format) foos#create |
||
213 | new_project_foo GET /projects/:project_id/foos/new(.:format) foos#new |
||
214 | edit_project_foo GET /projects/:project_id/foos/:id/edit(.:format) foos#edit |
||
215 | project_foo GET /projects/:project_id/foos/:id(.:format) foos#show |
||
216 | PUT /projects/:project_id/foos/:id(.:format) foos#update |
||
217 | DELETE /projects/:project_id/foos/:id(.:format) foos#destroy |
||
218 | </pre> |
||
219 | |||
220 | 1 | Mitsuyoshi Yoshida | この場合、アドレスは以下のようになります。 |
221 | <pre> |
||
222 | 6 | NAITOH Jun | アドレス: http://127.0.0.1/projects/demo/foos/1 |
223 | 3 | Mitsuyoshi Yoshida | params = {:project_id => "demo", :id => "1"} |
224 | 1 | Mitsuyoshi Yoshida | </pre> |
225 | |||
226 | フォームで送る場合はフォームの各フィールドのパラメータが params[:フォーム名] の子要素のハッシュで格納されて渡されます。 |
||
227 | |||
228 | <pre><code class="ruby"> |
||
229 | 6 | NAITOH Jun | <% form_for :foo, (モデルのオブジェクト), |
230 | :url=>project_foo_path("demo") do |f| %> |
||
231 | 1 | Mitsuyoshi Yoshida | <p> <%= f.text_field(:subject) %> </p> |
232 | <p> <%= f.text_area(:description) %> </p> |
||
233 | <%= f.submit l(:button_create) %> |
||
234 | <% end %> |
||
235 | </code></pre> |
||
236 | |||
237 | 5 | NAITOH Jun | <pre> |
238 | 3 | Mitsuyoshi Yoshida | アドレス: http://127.0.0.1/projects/demo/foos/new |
239 | 1 | Mitsuyoshi Yoshida | params = {:project_id => "demo", :foo=>{:subject=>(入力値), :description=>(入力値) } } |
240 | </pre> |
||
241 | |||
242 | |||
243 | h3. コントロール ← モデル |
||
244 | |||
245 | データベースからのデータの取得はモデルのクラスメソッドを使ってコントロール内で行います。 |
||
246 | |||
247 | <pre><code class="ruby"> |
||
248 | 4 | Mitsuyoshi Yoshida | Foo.find(:all, :conditions => ["project_id = #{@project.id} "]) # project_id の一致する全要素を取得 |
249 | Foo.find(:first, :conditions => ["id = #{params[:id]} "]) # id の一致する最初の要素を取得 |
||
250 | 1 | Mitsuyoshi Yoshida | Foo.find_by_id(params[:id]) # 前の簡易版 |
251 | </code></pre> |
||
252 | |||
253 | データベースに変更を加える場合には Foo のオブジェクトのメソッドを使用します。 |
||
254 | |||
255 | |_. 操作 |_. 関数 |_. 説明 | |
||
256 | | 追加 | foo.save | id メンバが 0 で保存をすると新しいレコードとして追加されます。追加の際 id が連番で割り振られます。| |
||
257 | | 更新 | foo.save | id が 0 以外の場合には対象となるレコードが更新されます。 | |
||
258 | | 削除 | foo.destory | テーブルからレコードが削除されます | |
||
259 | |||
260 | |||
261 | h3. コントロール → ビュー |
||
262 | |||
263 | ビューの Erb ファイルの評価はコントロール内で行われるので、コントロールクラスのインスタンス変数(@)はビュー内でもそのまま使用できます。 |
||
264 | |||
265 | |||
266 | h1. 終わりに |
||
267 | |||
268 | 以上でプラグインの開発ガイドは終了です。 |
||
269 | 作成方法の基本はご理解いただけたでしょうか。 |
||
270 | |||
271 | 実際にプラグインを作ろうと思った場合、ガイドの知識だけでは不足すると思います。そういったときは [[プラグイン_Tips]] を見てください。こちらには応用的な機能の実現方法が紹介されています。 |
||
272 | そこにも知りたい内容がない場合は、他のプラグインや Redmine 自身のソースを見てください。おそらくソースの中身が大分読みやすくなっているのではないでしょうか。 |
||
273 | |||
274 | これから Redmine に不足を感じたら、自分でプラグインを作って満足のいく Redmine に仕上げていってください。 |
||
275 | そしてプラグインができたらどんどん公開して、みんなで Redmine をいいソフトにしていきましょう。 |
||
276 | |||
277 | |||
278 | --- |
||
279 | |||
280 | | [[プラグイン開発ガイド|^]] | [[GuideActionElse|<<]] | |