Ruby on Railsでヘッダディテール型(親子テーブル)のデータを1画面で表現、登録する。
ヘッダディテール型、ヘッダのテーブルと明細のテーブルが1つになった画面を作りたいと思います。
実装仕様(イメージ)について
ヘッダと明細が同じ画面で表示されて、それを更新するパターン
実装環境
今回の利用したRails環境は以下のとおりです。
OS: Windows XP (そろそろ変えたい…そればっかやな…)
Ruby: Ruby 2.0.0p247
Rails: Rails 4.0.0
* 前回の記事内容のDevise実装が出来ている事とします。
実施内容
テスト用の新規アプリを作成
$ rails new headerdetail --no-test-framework
ヘッダのモデル・ビュー・コントローラを作る(Scaffoldを利用)
$ rails generate scaffold header header_number:integer header_description:string
明細(ディテール)のモデルを作る ※明細はモデルのみで対応するビュー等は必要ない。
$ rails generate model detail detail_number:integer detail_description:string header_id:integer
DB定義を反映する
$ bundle exec rake db:migrate
モデルに親子関係を記載する。
1.ヘッダ側のファイル
ファイル:app/models/header.rb
以下の記述を追加
has_many :details
accepts_nested_attributes_for :details, allow_destroy: true
2.明細側のファイル
ファイル:app/models/detail.rb
以下の記述を追加
belongs_to :header
validates :header_id, ;detail_number, presence: true
コントローラを修正する。
ファイル:app/controllers/header_controller.rb
1. newメソッドにヘッダの行を追加(とりあえず3行)
そのうち、手動で増やすオプションが必要だと思われるが、それは別途調べる事にする。
def new
@header = Header.new
#ここから追加
3.times{
@header.details.build
}
end
2. Strong Parametersをいじる。これは資料が少なくて結構ハマったけど、明細側のファイルは :(明細モデル)_attributes => [:id, :_destroy, (要素)]となるようです。
def header_params
params.require(:header).permit(:header_number, :header_description,
:details_attributes => [:id, :detail_number, :detail_description, :_destroy])
end
ビューを修正する。明細の表示を追加
ファイル:app/views/headers/_form.html.erb
<div class="field">
<%= f.fields_for :details do |dtl| %>
<%= dtl.label :detail_number %><br/>
<%= dtl.number_field :detail_number %><br/>
<%= dtl.label :detail_description %><br/>
<%= dtl.text_field :detail_description %><br/>
<% end %>
</div>
これで、レイアウトの問題は無視して、とりあえずヘッダと明細の同時更新が可能になりました。今日は疲れたので、ここまでとします。