GuideNewAction » 履歴 » バージョン 9
NAITOH Jun, 2013/04/14 21:29
RESTfulな実装に変更。
1 | 1 | Mitsuyoshi Yoshida | h1. 新規作成(new) アクション |
---|---|---|---|
2 | |||
3 | 6 | Mitsuyoshi Yoshida | 新しいデータを作成するためのアクションを実装します。 |
4 | 1 | Mitsuyoshi Yoshida | このページは一覧表示ページから呼ばれることになります。 |
5 | |||
6 | |||
7 | h2. 新規作成ページの仕様 |
||
8 | |||
9 | まず、作成する新規作成ページの動きについてもう少し細かく決めておきましょう。 |
||
10 | 新規作成ページではパラメータを指定して、新しいデータを作成することになります。サンプルでは題名(subject)と説明(decription)です。説明は wiki で記述できるようにします。通常の wiki のように添付ファイルやプレビューまでつけようとすると少し複雑になりますが、 wiki 形式にするだけならば結構簡単にできます。 |
||
11 | 5 | Mitsuyoshi Yoshida | それらの機能が付いた wiki の作成については [[Tips wiki|プラグイン Tips]] を見てください。 |
12 | 1 | Mitsuyoshi Yoshida | |
13 | !new.png! |
||
14 | |||
15 | チケットでは [作成] ボタンを押すとチケットが作成されて詳細情報のページになります。サンプルでも [作成] 後には詳細説明のページになるようにします。 |
||
16 | また、チケットと同様に題名に何も入力されていないとエラーメッセージがでて、データが作成されないようにもします。 |
||
17 | |||
18 | |||
19 | |||
20 | 8 | NAITOH Jun | h2. GET と POST と PUT |
21 | 1 | Mitsuyoshi Yoshida | |
22 | 9 | NAITOH Jun | コントローラ → ビュー のデータのデータの受け渡しではインスタンス変数を使用することが出来ました。 create では逆に ビュー → コントローラ の方向でデータを受け渡す必要があります。Rails ではこの場合 CGI の GET や POST や PUT を使ってデータを受け取ることになります。 |
23 | 1 | Mitsuyoshi Yoshida | |
24 | よく検索サイトや辞書サイトではアドレスの後に ? が付いていろいろとパラメータが設定されていると思います。このようにアドレスにつけてパラメータを渡す方法を *GET* といいます。この方法の利点はアドレスにつけて渡すので、検索条件込みでリンクをつくることができる点です。プラグインを作る場合でもフィルタなどの検索を使う場合にはパラメータの受け渡しには GET を使った方がいいでしょう。 |
||
25 | 9 | NAITOH Jun | [[GuideForProject|プロジェクトメニューのリンク]] では project_id の値をパラメータとして渡していました。これは GET でパラメータを渡すことになります。 Rails では url の指定をパスやハッシュで行った場合、コントロール、アクション、 ID 以外のパラメータはデフォルトでは GET として渡されるためです。 |
26 | 1 | Mitsuyoshi Yoshida | |
27 | 9 | NAITOH Jun | GET ではアドレスとしてパラメータを持たせるため、あまり長いパラメータの場合には不向きですし、 255 文字という制限があります。その場合には *POST* (もしくは *PUT*)を使ってデータを送信することになります。 Rails ではフォームでパラメータを送ろうとするとデフォルトは新規作成の場合は *POST* 、更新の場合は *PUT* でデータを送信します。 |
28 | 1 | Mitsuyoshi Yoshida | |
29 | 8 | NAITOH Jun | ただし、 Rails では受け取る場合その違いを意識する必要はありません。 GET や POST、PUT で受け渡されるデータはキーと値のペアなのですが、これらは params 変数のハッシュの中に格納されます。 |
30 | 1 | Mitsuyoshi Yoshida | つまり、 ビュー → コントローラでデータを受け取る場合には params 変数で行うことになります。 |
31 | |||
32 | !view_control.png! |
||
33 | |||
34 | h2. コントローラの実装 |
||
35 | |||
36 | 9 | NAITOH Jun | コントローラ(app/controllers/foos_controller.rb) の new および create メソッドを実装します。 |
37 | 1 | Mitsuyoshi Yoshida | |
38 | 9 | NAITOH Jun | h3. 新規作成フォーム( new アクション ) |
39 | |||
40 | 1 | Mitsuyoshi Yoshida | <pre><code class="ruby"> |
41 | 9 | NAITOH Jun | @foo = Foo.new() |
42 | </code></pre> |
||
43 | |||
44 | new アクションは一覧表示のリンクから呼び出されます。 |
||
45 | Foo モデルクラスのオブジェクトを新規作成します。 |
||
46 | |||
47 | h3. 作成( create アクション ) |
||
48 | |||
49 | 続いて create メソッドを実装します。 |
||
50 | |||
51 | create はコントローラのスケルトンで作成していませんでした。そこで中身だけでなく、定義からコントローラ(foos_controller.rb)に記述することになります。 |
||
52 | |||
53 | <pre><code class="ruby"> |
||
54 | def create |
||
55 | 1 | Mitsuyoshi Yoshida | @foo = Foo.new(params[:foo]) |
56 | @foo.project_id = @project.id |
||
57 | |||
58 | 9 | NAITOH Jun | if @foo.save |
59 | 1 | Mitsuyoshi Yoshida | flash[:notice] = l(:notice_successful_create) |
60 | 9 | NAITOH Jun | redirect_to project_foo_path(@project, @foo.id) |
61 | 1 | Mitsuyoshi Yoshida | end |
62 | 9 | NAITOH Jun | end |
63 | 1 | Mitsuyoshi Yoshida | </code></pre> |
64 | |||
65 | 9 | NAITOH Jun | 新規作成画面で [作成] ボタンが押された後、create アクションが実行されます。 |
66 | 1 | Mitsuyoshi Yoshida | |
67 | 9 | NAITOH Jun | @params[:foo]@ は、 :foo をキーとした場合にはハッシュになっていて、そこに :subject や :description をキーとして値が入っています。例えば説明の中身を取り出したい場合は @params[:foo][:description]@ でアクセスすることが出来ます。 |
68 | 1 | Mitsuyoshi Yoshida | Foo.new の引数として、このハッシュを渡すことでメンバにそのハッシュの中身が格納されたオブジェクトが作成されます。 |
69 | |||
70 | 9 | NAITOH Jun | save はオブジェクトの中身をレコードとしてデータベースに保存する Foo モデルのメソッドです。 |
71 | 1 | Mitsuyoshi Yoshida | |
72 | 9 | NAITOH Jun | 保存が成功したあとに実行されているコードはチップの作成時にでてくるような"作成されたました"といったメッセージを出力するためのものです。 |
73 | その後 *redirect_to* を使い project_foo_path に変更しています。これにより新規作成ページではなく、詳細ページが表示されることになります。 redirect_to に渡す引数はリンクなどでの URL 指定の場合と同じです。 |
||
74 | 1 | Mitsuyoshi Yoshida | |
75 | |||
76 | h2. ビューの実装 |
||
77 | |||
78 | 次にビュー (app/views/foos/new.html.erb) を実装します。 |
||
79 | 8 | NAITOH Jun | |
80 | 9 | NAITOH Jun | <pre><code class="erb"> |
81 | <%= labelled_form_for :foo, @foo, |
||
82 | :url => project_foos_path(@project) do |f| %> |
||
83 | 1 | Mitsuyoshi Yoshida | <%= render :partial => 'foos/form', :locals => {:form => f} %> |
84 | <%= f.submit l(:button_create) %> |
||
85 | <% end %> |
||
86 | </code></pre> |
||
87 | |||
88 | |||
89 | h3. 部分描画 |
||
90 | |||
91 | 新規作成と編集ページではほぼ同じ画面となります。 同じようなことを何度も書くのは DRY じゃありません |
||
92 | 8 | NAITOH Jun | 他のプログラミングでは同じような部分があった場合、共通部分を関数として抜き出したりします。 Rails のビューの描画でも同様に共通の描画部分を分けることが出来ます。 |
93 | 1 | Mitsuyoshi Yoshida | |
94 | それが new.html.erb の 2 行目の render の部分になります。 |
||
95 | *":partial=>'foos/form'* で共通部分を記述しているファイルを指定しています。指定は app/views 以下のパスで指定するのですが、実際のファイルは *app/views/foos/_form.html.erb* となります。つまり、実際には先頭に _ アンダーバーを付けて、拡張子を付加したものが検索されます。 |
||
96 | 関数に引数を渡すようなことが *:locals* で出来ます。ここでは f で指定されたオブジェクトが部分描画のファイル内では form という変数名で使用できるようにになります。 |
||
97 | |||
98 | |||
99 | 8 | NAITOH Jun | h3. フォーム |
100 | 1 | Mitsuyoshi Yoshida | |
101 | new では作成時のパラメータの設定に html のフォームを使います。 *labelled_form_for* は Rails で通常使われる *form_for* メソッドをを拡張したもので、フォーム内のラベルとフィールドがテーブルのように配列されます。methodの引数は form_for と同じです。 |
||
102 | 3 | Mitsuyoshi Yoshida | |
103 | 8 | NAITOH Jun | 第一引数はフォームの名前です。:foo を指定していますのでフォーム内で指定されるパラメータは params[:foo] のハッシュに格納されることになります。 |
104 | 1 | Mitsuyoshi Yoshida | 第二引数はモデルクラスのオブジェクトを指定します。このオブジェクトの各メンバの値が対応するパラメータのフィールドにおけるデフォルト値となります。ただし、Foo.new される際特にメンバにデフォルト値を設定していませんので、各パラメータのデフォルト値は空文字になります。 |
105 | 9 | NAITOH Jun | 第三引数は *:url* シンボルを使ってパスを指定します。ここでは自動的に POST として処理されるため create アクションが実行されることになります。 id 省略時には現在のものが使用されます。なお、リンクの url 指定の場合には id は省略されると空になるので省略はできません。 |
106 | 1 | Mitsuyoshi Yoshida | |
107 | labelled_form_for のメソッドのブロック内でフォームの各フィールドを設定します。各フィールドは f.submit ボタンのようにブロックの引数 @f@ を使って設定します。 |
||
108 | |||
109 | |||
110 | 8 | NAITOH Jun | h3. フォーム内のパラメータ |
111 | 1 | Mitsuyoshi Yoshida | |
112 | app/views/foos/_form.html.erb の中身は次のようになります。 |
||
113 | |||
114 | 9 | NAITOH Jun | <pre><code class="erb"> |
115 | 1 | Mitsuyoshi Yoshida | <%= error_messages_for 'foo' %> |
116 | <div class="box"> |
||
117 | <p><%= form.text_field :subject, |
||
118 | :size => 100, :required => true %></p> |
||
119 | <p><%= form.text_area :description, |
||
120 | :class => 'wiki-edit' %></p> |
||
121 | <%= wikitoolbar_for 'foo_description' %> |
||
122 | </div> |
||
123 | </code></pre> |
||
124 | |||
125 | これが new.html.erb の render :partial の部分に入ることになります。 |
||
126 | |||
127 | 1 行目ではエラーメッセージの表示を指定しています。 foo という名前のフォーム内で入力にエラーがあった場合にエラーメッセージが表示されるようになっています。 |
||
128 | |||
129 | 8 | NAITOH Jun | *box* クラスのブロックは設定ダイアログのように背景を灰色にするためのものです。 |
130 | 1 | Mitsuyoshi Yoshida | |
131 | :locals のオプションで設定したようにこのファイル内では form が labelled_form_for のブロック変数です。これを使ってパラメータ用の各フィールドが配置されています。 |
||
132 | |||
133 | |_. 対象 |_. パラメータ名 |_. フィールドタイプ |_. ラベルのシンボル | |
||
134 | | 題名 | subject | テキストフィールド | field_subject | |
||
135 | | 説明 | description | テキストエリア | field_description | |
||
136 | |||
137 | ラベルは省略しているため、 *field_パラメータ名* というシンボルに対応するメッセージが使用されます。それぞれのメッセージ定義は Redmine のメッセージファイルにあります。 |
||
138 | |||
139 | subject テキストフィールドのオプションでは、まずデフォルトでは幅が少し短いので :size で幅を指定しています。 次の :required オプションで true を指定しています。これは必ず入力しなければならないことを表す %{color:red}*% を付けるためのものです。ただし、これはマークを付けているだけでこのオプションで空文字の入力のエラー判定まで行ってくれるわけではありません。エラーチェックをする方法は次節で実装します。 |
||
140 | 4 | Mitsuyoshi Yoshida | |
141 | 1 | Mitsuyoshi Yoshida | description テキストエリアでは wiki 入力ようにするため 2 つのことを行っています。 |
142 | |||
143 | * CSS の *wiki-edit* クラスにする |
||
144 | * *wikitoolbar_for* メソッドで wiki 編集用のツールボックスをつける |
||
145 | 引数で foo フィールドの description のテキストエリアを指定 |
||
146 | |||
147 | |||
148 | 8 | NAITOH Jun | h2. モデルの実装 |
149 | 1 | Mitsuyoshi Yoshida | |
150 | パラメータの値が妥当かどうかのチェックはモデル (app/models/foo.rb) に記述します。 |
||
151 | この処理は ActiveRecord::Base クラスの *validate* メソッドをオーバーライドして実装します。しかし、空文字のチェックなどよく使われるチェックには便利なメソッドが用意されています。サンプルではこちらを使用します。 |
||
152 | |||
153 | <pre><code class="ruby"> |
||
154 | class Foo < ActiveRecord::Base |
||
155 | unloadable |
||
156 | |||
157 | validates_presence_of :subject |
||
158 | validates_length_of :subject, :maximum => 255 |
||
159 | |||
160 | end |
||
161 | </code></pre> |
||
162 | |||
163 | スケルトンで出力されたものに 4, 5 行目を追加しています。 |
||
164 | 4 行目の *validates_presence_of* で subject パラメータで未設定(空文字)を禁止しています。 |
||
165 | 5 行目の *validates_length_of* で subject パラメータの文字数の最大値を指定しています。 subject は string 型なので 255 文字の制限がありました。そのため 255 文字以上入力するとエラーとなるようにしています。 |
||
166 | |||
167 | |||
168 | --- |
||
169 | |||
170 | | [[プラグイン開発ガイド|^]] | [[GuideIndexAction|<<]] | [[GuideActionElse|>>]] | |