
By: Jonathan Combe – CC BY 2.0
前提
テンプレートからデータを代入してdocxを作れるようになったけど、実際には過去のデータを流用して新しいdocxを作りたいことがよくある.
ので、過去のデータで新規作成をできるようにしてみた.
構想
ここではとりあえず、前のデータを使って新規作成の動作は、documents#newにやらせることにした.
前にtemplates#showにdocument新規作成のformを作ったのでdocuments#newは使ってなかったから.
1 | renew_document /documents/:id/new(.:format) documents#new |
というふうに定義することにした.
routes.rb
なので、config/routes.rbのresource :documentsより前に次のように書いた
1 | match 'documents/:id/new(.:format)', to: 'documents#new', as: 'renew_document' |
view
次にtemplates#showに一覧表示しているdocumentsの一覧から、前のデータを使って新規作成をやりたいのでNewへのリンクを作った.
1 2 3 4 | <td><%= link_to 'Show', document %></td> <td><%= link_to 'Edit', edit_document_path(document) %></td> <td><%= link_to 'Destroy', document, method: :delete, data: { confirm: 'Are you sure?' } %></td> <td><%= link_to 'New', renew_document_path(document) %></td> |
これでrenew_document_path(document)が、documents/#{document.id}/newというパスを生成してくれる
そして、リンク先のコントローラーでparams[:id]でdocument.idを読める.
documents_controller
フォーム用のモデルとフォームに代入するデータの準備をする.2つの配列からハッシュをつくるのはここを参照した.to_hashを定義してもいいかな.あとsplitとかはいい加減modelに回したい.
1 2 3 4 5 6 7 | @document = Document.new document_for_form = Document.find(params[:id]) @document.template_id = document_for_form.template_id key_array = @document.template.scheme.split(',') value_array = document_for_form.data.split(',') array = [key_array, value_array].transpose @data = Hash[*array.flatten] |
view
で、_formは前のままで
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <div> <%= f.label :template_id %><br /> <%= f.number_field :template_id %> </div> <% @document.template.scheme.split(',').each do |label| %> <div> <%= label.gsub(/@@/, '') %> <%= text_field_tag label, @data[label] %> </div> <% end %> <div> <%= f.submit %> </div> |
DEKITA
こんなデータでnewリンクをクリックすると
前のデータが入力された状態でCreate Documentになってる
*データベースのスキームを直したので普通にdocument.newに初期値を設定すればOKになりました.accepts_nested_attributes_forを設定しているので、document.value.buildを必要な回数分だけやれば関連フォームを必要な分用意してくれます.
1 2 3 4 5 | document_for_form = Document.find(params[:id]) @document = Document.new(name: document_for_form.name, template_id: document_for_form.template_id) document_for_form.values.each do |value| @document.values.build(key_id: value.key_id, content: value.content) end |
参考