テーブルに1行だけ追加する。

ファイルのアップロードをモーダルウィンドウ化したことで、背景に透過したリストページでアップロードしたファイルが常に確認出来るようになった、と喜んでいたが、まだまだ問題あり。並び替えのキー列が「アップロード日時」で「降順」なら、リストの1行目に追加されて確認できるが、それ以外の並べ替え方法では見えない位置に追加されるので、ファイルの確認が出来ない状態であった...。解決するために、二つの方法が思い浮かんだ。

  1. 強制的に並べ替え順序を「アップロード日時」で「降順」に変更して、リスト全体を更新する。
  2. 並び替え順序は変更せずに、リストの1行目に1行だけ追加する。

リスト全体を更新する方法

現状はリスト全体を更新する方法で処理しているので、1.の方法なら手っ取り早く実現できる。

app/views/new.rhtml
ビュー(アップロードページを描画)
  • 親ウィンドウを更新するJavaScriptに、urlにパラメーターとして並べ替え方法を追加した。(ついでに1ページ目の指定もした。)
  • このJavaScriptは、new.rhtmlを描画する度に実行される。
<%= javascript_tag(
      remote_parent :update=>'list_update', 
                    :url=>{:action=>:list_update, 
                           :sort_field=>'created_at', 
                           :sort_direction=>'desc', 
                           :page=>1}
) unless params[:id].blank? %>
...(以下省略、アップロードページを描画する部分)...

1行だけ追加する方法

でも、いろいろ考えて*1今回は2.の方法でやってみることにした。

失敗例
app/views/new.rhtml
ビュー(アップロードページを描画)
  • :position=>:afterは、指定要素の直後に追加する指定。
      • :before
      • <tr id="listh">
      • :top
      • 既存の表示内容
      • :bottom
      • </tr>
      • :after
<%= javascript_tag(
      remote_parent :update=>'listh', 
                    :submit=>'list_params', 
                    :url=>{:action=>:add_list, 
                           :id=>params[:id]}, 
                    :position=>:after
) unless params[:id].blank? %>
...(以下省略、アップロードページを描画する部分)...
app/controllers/csvs_controller.rb
コントローラー
  • add_listアクションを追加して、_listd.rhtmlを1行だけ描画するようにした。
class CsvsController < ApplicationController
...(途中省略)...
  def add_list
    @csv = Csv.find(params[:id])
    render :partial=>'listd'
  end
app/views/_listd.rhtml
ビュー(リストのデータ行を描画する部分)
  • :collectionオプションを設定した時と、変数の渡し方が異なるので補正
<% @csv = listd unless listd.blank? %>
<% listd = @csv if listd.blank? %>
...(以下省略)...

一見、これで問題なく1行追加出来そうなんだが、完全には思い通りに動かなくて悩んでしまった。確かに狙った位置に1行追加されるのだが、以下の問題が解決出来なかった...。なぜだろう?

成功例

上記の失敗例の原因は、結局分からないまま...。でも、解決策は見つかった。同じことをrender :updateで処理すると思い通りの結果になったのだ!

app/views/new.rhtml
ビュー(アップロードページを描画)
  • render :updateで描画する時は、部分更新の位置を指定する:update=>'listh'は削除する。:updateオプションが残っていると正常に描画できない。
<%= javascript_tag(
      remote_parent :submit=>'list_params', 
                    :url=>{:action=>:add_list, 
                           :id=>params[:id]}
) unless params[:id].blank? %>
...(以下省略、アップロードページを描画する部分)...

app/controllers/csvs_controller.rb
コントローラー
  • 部分更新の位置は、render :updateの中で個別に指定する。
class CsvsController < ApplicationController
...(途中省略)...
  def add_list
    @csv = Csv.find(params[:id])
    render :update do |p|
      p.insert_html(:after, 'listh', :partial=>'listd')
    end
  end


以上で、アップロードしたファイルは常に1行目に追加されるようになった!

*1:勝手に並べ替え方法を変更してしまうのはちょっと乱暴な気もする。また、リスト全体が100行だった場合を考えると、1行追加するのに100行描画することになり、無駄が多い。