Project

General

Profile

Actions

新規作成(new) アクション

新しいデータを作成するためのアクションを実装します。
このページは一覧表示ページから呼ばれることになります。

新規作成ページの仕様

まず、作成する新規作成ページの動きについてもう少し細かく決めておきましょう。
新規作成ページではパラメータを指定して、新しいデータを作成することになります。サンプルでは題名(subject)と説明(decription)です。説明は wiki で記述できるようにします。通常の wiki のように添付ファイルやプレビューまでつけようとすると少し複雑になりますが、 wiki 形式にするだけならば結構簡単にできます。
それらの機能が付いた wiki の作成については プラグイン Tips を見てください。

チケットでは [作成] ボタンを押すとチケットが作成されて詳細情報のページになります。サンプルでも [作成] 後には詳細説明のページになるようにします。
また、チケットと同様に題名に何も入力されていないとエラーメッセージがでて、データが作成されないようにもします。

GET と POST と PUT

コントローラ → ビュー のデータのデータの受け渡しではインスタンス変数を使用することが出来ました。 create では逆に ビュー → コントローラ の方向でデータを受け渡す必要があります。Rails ではこの場合 CGI の GET や POST や PUT を使ってデータを受け取ることになります。

よく検索サイトや辞書サイトではアドレスの後に ? が付いていろいろとパラメータが設定されていると思います。このようにアドレスにつけてパラメータを渡す方法を GET といいます。この方法の利点はアドレスにつけて渡すので、検索条件込みでリンクをつくることができる点です。プラグインを作る場合でもフィルタなどの検索を使う場合にはパラメータの受け渡しには GET を使った方がいいでしょう。
プロジェクトメニューのリンク では project_id の値をパラメータとして渡していました。これは GET でパラメータを渡すことになります。 Rails では url の指定をパスやハッシュで行った場合、コントロール、アクション、 ID 以外のパラメータはデフォルトでは GET として渡されるためです。

GET ではアドレスとしてパラメータを持たせるため、あまり長いパラメータの場合には不向きですし、 255 文字という制限があります。その場合には POST (もしくは PUT)を使ってデータを送信することになります。 Rails ではフォームでパラメータを送ろうとするとデフォルトは新規作成の場合は POST 、更新の場合は PUT でデータを送信します。

ただし、 Rails では受け取る場合その違いを意識する必要はありません。 GET や POST、PUT で受け渡されるデータはキーと値のペアなのですが、これらは params 変数のハッシュの中に格納されます。
つまり、 ビュー → コントローラでデータを受け取る場合には params 変数で行うことになります。

コントローラの実装

コントローラ(app/controllers/foos_controller.rb) の new および create メソッドを実装します。

新規作成フォーム( new アクション )

    @foo = Foo.new()

new アクションは一覧表示のリンクから呼び出されます。
Foo モデルクラスのオブジェクトを新規作成します。

作成( create アクション )

続いて create メソッドを実装します。

create はコントローラのスケルトンで作成していませんでした。そこで中身だけでなく、定義からコントローラ(foos_controller.rb)に記述することになります。

  def create
    @foo = Foo.new(params[:foo])
    @foo.project_id = @project.id

    if @foo.save    
      flash[:notice] = l(:notice_successful_create)
      redirect_to project_foo_path(@project, @foo.id)
    end
  end

新規作成画面で [作成] ボタンが押された後、create アクションが実行されます。

params[:foo] は、 :foo をキーとした場合にはハッシュになっていて、そこに :subject や :description をキーとして値が入っています。例えば説明の中身を取り出したい場合は params[:foo][:description] でアクセスすることが出来ます。
Foo.new の引数として、このハッシュを渡すことでメンバにそのハッシュの中身が格納されたオブジェクトが作成されます。

save はオブジェクトの中身をレコードとしてデータベースに保存する Foo モデルのメソッドです。

保存が成功したあとに実行されているコードはチップの作成時にでてくるような"作成されたました"といったメッセージを出力するためのものです。
その後 redirect_to を使い project_foo_path に変更しています。これにより新規作成ページではなく、詳細ページが表示されることになります。 redirect_to に渡す引数はリンクなどでの URL 指定の場合と同じです。

ビューの実装

次にビュー (app/views/foos/new.html.erb) を実装します。

<%= labelled_form_for :foo, @foo,
                  :url => project_foos_path(@project) do |f| %>
    <%= render :partial => 'foos/form', :locals => {:form => f} %>
    <%= f.submit l(:button_create) %>
<% end %>

部分描画

新規作成と編集ページではほぼ同じ画面となります。 同じようなことを何度も書くのは DRY じゃありません
他のプログラミングでは同じような部分があった場合、共通部分を関数として抜き出したりします。 Rails のビューの描画でも同様に共通の描画部分を分けることが出来ます。

それが new.html.erb の 2 行目の render の部分になります。
":partial=>'foos/form' で共通部分を記述しているファイルを指定しています。指定は app/views 以下のパスで指定するのですが、実際のファイルは app/views/foos/_form.html.erb となります。つまり、実際には先頭に _ アンダーバーを付けて、拡張子を付加したものが検索されます。
関数に引数を渡すようなことが :locals で出来ます。ここでは f で指定されたオブジェクトが部分描画のファイル内では form という変数名で使用できるようにになります。

フォーム

new では作成時のパラメータの設定に html のフォームを使います。 labelled_form_for は Rails で通常使われる form_for メソッドをを拡張したもので、フォーム内のラベルとフィールドがテーブルのように配列されます。methodの引数は form_for と同じです。

第一引数はフォームの名前です。:foo を指定していますのでフォーム内で指定されるパラメータは params[:foo] のハッシュに格納されることになります。
第二引数はモデルクラスのオブジェクトを指定します。このオブジェクトの各メンバの値が対応するパラメータのフィールドにおけるデフォルト値となります。ただし、Foo.new される際特にメンバにデフォルト値を設定していませんので、各パラメータのデフォルト値は空文字になります。
第三引数は :url シンボルを使ってパスを指定します。ここでは自動的に POST として処理されるため create アクションが実行されることになります。 id 省略時には現在のものが使用されます。なお、リンクの url 指定の場合には id は省略されると空になるので省略はできません。

labelled_form_for のメソッドのブロック内でフォームの各フィールドを設定します。各フィールドは f.submit ボタンのようにブロックの引数 f を使って設定します。

フォーム内のパラメータ

app/views/foos/_form.html.erb の中身は次のようになります。

<%= error_messages_for 'foo' %>
<div class="box">
<p><%= form.text_field :subject,
                       :size => 100, :required => true %></p>
<p><%= form.text_area :description,
                      :class => 'wiki-edit' %></p>
<%= wikitoolbar_for 'foo_description' %>
</div>

これが new.html.erb の render :partial の部分に入ることになります。

1 行目ではエラーメッセージの表示を指定しています。 foo という名前のフォーム内で入力にエラーがあった場合にエラーメッセージが表示されるようになっています。

box クラスのブロックは設定ダイアログのように背景を灰色にするためのものです。

:locals のオプションで設定したようにこのファイル内では form が labelled_form_for のブロック変数です。これを使ってパラメータ用の各フィールドが配置されています。

対象 パラメータ名 フィールドタイプ ラベルのシンボル
題名 subject テキストフィールド field_subject
説明 description テキストエリア field_description

ラベルは省略しているため、 field_パラメータ名 というシンボルに対応するメッセージが使用されます。それぞれのメッセージ定義は Redmine のメッセージファイルにあります。

subject テキストフィールドのオプションでは、まずデフォルトでは幅が少し短いので :size で幅を指定しています。 次の :required オプションで true を指定しています。これは必ず入力しなければならないことを表す * を付けるためのものです。ただし、これはマークを付けているだけでこのオプションで空文字の入力のエラー判定まで行ってくれるわけではありません。エラーチェックをする方法は次節で実装します。

description テキストエリアでは wiki 入力ようにするため 2 つのことを行っています。

  • CSS の wiki-edit クラスにする
  • wikitoolbar_for メソッドで wiki 編集用のツールボックスをつける
    引数で foo フィールドの description のテキストエリアを指定

モデルの実装

パラメータの値が妥当かどうかのチェックはモデル (app/models/foo.rb) に記述します。
この処理は ActiveRecord::Base クラスの validate メソッドをオーバーライドして実装します。しかし、空文字のチェックなどよく使われるチェックには便利なメソッドが用意されています。サンプルではこちらを使用します。

class Foo < ActiveRecord::Base
  unloadable

  validates_presence_of :subject
  validates_length_of :subject, :maximum => 255

end

スケルトンで出力されたものに 4, 5 行目を追加しています。
4 行目の validates_presence_of で subject パラメータで未設定(空文字)を禁止しています。
5 行目の validates_length_of で subject パラメータの文字数の最大値を指定しています。 subject は string 型なので 255 文字の制限がありました。そのため 255 文字以上入力するとエラーとなるようにしています。


^ << >>


Updated by NAITOH Jun , Updated over 11 years ago
Access count: 28386 :since 2009-10-30

Updated by NAITOH Jun over 11 years ago · 9 revisions