CSVサーバー0.1
CSVサーバーは、表計算ソフトで作成した資料を、社内のネットワークで簡単に公開できることを目指して作成中のWEBアプリケーションです。Ruby on Railsの勉強も兼ねているので、まだまだ不完全な部分も多く、思い通りの動作をしない可能性もあります。
唯一の特徴は、社内向けに閲覧制限を設定することが可能なことです。表の中にpath列を設定しておくと、その行はpath列の部署名のユーザーのみ閲覧可能になります。その詳細については、以前の日記の以下のタイトルを紹介しておきます。
また、アップロードしたCSVファイルを柔軟に検索(フィルタ)できるように心掛けました。検索(フィルタ)機能の詳細については、以下のタイトルを紹介しておきます。
CSVサーバーへのログイン
テスト用の運用ページから、以下のユーザーでログインすることがきます。自由に試して頂いて結構です。(システム管理者でログインすれば全ての権限が手に入ります。その場合、好奇心旺盛に設定を変更してしまうと、CSVサーバーはダウンしてしまうかもしれませんが...。)
ログイン名 | パスワード | 権限 | 閲覧可能な部署 | 管理部門 |
---|---|---|---|---|
yamada | yamada | CSVファイルの閲覧のみ | /株式会社RAILS/営業1部/営業1課/, /株式会社RAILS/営業1部/営業3課/ | 無し |
suzuki | suzuki | CSVファイルのアップロードと閲覧 | /株式会社RAILS/ | 経理部 |
satou | satou | CSVファイルのアップロードと閲覧 | /株式会社RAILS/ | 人事部 |
zarigani | zarigani | システム管理者であり、全ての権限 | /株式会社RAILS/ | 総務部、人事部、経理部 |
productionモードまでの更新履歴
bootstrapの実行と、権限の設定。これを忘れると、Admin権限以外では正常に機能しなくて悩むことになる。
その変更に伴い、検索アイテムを未入力の場合(filter_itemがブランクまたは空白文字の場合)は、フィルター処理を無視するようにした。以下のようにやってみたが、とても分かり難い処理になってしまった...。
- app/models/filter_sql.rb
- モデル
def self.human_compair_sql(column, item, id) f = Filtersql.find(id) # itemが未入力または、空白文字の時は、フィルター無しの条件を設定する。 item_eval = eval(f.item || '') if item_eval.nil? && (item.empty? || /\s+/ =~ item) f = Filtersql.find(20) item = eval(f.item || '') end # 必ず、option = 、item = の順に実行すること。 # eval("AND '#{end_at_period(item)}'")の場合はitemの値に影響されるため。 option = eval(f.option || '') item = item_eval || item || '%' #"(#{f.not_op} #{column} #{f.operator} '#{f.wild1}#{item}#{f.wild2}' #{option})" sql = "(#{f.not_op} #{column} #{f.operator} ? #{option})" sanitize_sql([sql, "#{f.wild1}#{item}#{f.wild2}"]) end
管理部門、アップロード担当者のフィルターのデフォルト値を自分自身の設定にする。選択した自分自身の設定が存在しない場合はブランクになる。
- app/views/csvs/_filter_management_section_id.rhtml
- ビュー
<% options = Csv.find(:all, :include => :management_section).map do |c| [c.management_section.name, c.management_section_id] end.uniq.unshift(@no_select) %> <% selected_item = current_user.management_sections[0].id rescue nil %> <%= select_tag :filter_item, options_for_select(options, selected_item), :name => "filter[#{@filter_count}][item]" %> <% items = Filterset.find_by_name('select').filtersqls.map{|f| [f.name, f.id]} %> <%= select_tag :filter_id, options_for_select(items, params[:filter_id].to_i), :name => "filter[#{@filter_count}][id]" %>
- app/views/csvs/_filter_user_id.rhtml
- ビュー
<% options = Csv.find(:all, :include => :user).map do |c| ["#{c.user.lastname} #{c.user.firstname}", c.user_id] end.uniq.unshift(@no_select) %> <%= select_tag :filter_item, options_for_select(options, current_user.id), :name => "filter[#{@filter_count}][item]" %> <% items = Filterset.find_by_name('select').filtersqls.map{|f| [f.name, f.id]} %> <%= select_tag :filter_id, options_for_select(items, params[:filter_id].to_i), :name => "filter[#{@filter_count}][id]" %>
CSVファイルへのリンクをクリックした時は、新規ウィンドウで表示するようにした。以下のように:popup=>trueオプションを追加するだけでOK。ちなみに:popup => ['new_window_name', 'height=300,width=600']のように指定すれば、ウィンドウのタイトルとサイズも指定可能。
<%= link_to h(listd.file_name), {:controller => 'displays', :action=>'list', :table => listd.csv_table, :editable => listd.editable}, :popup => true %>
CSVリストページで、編集、削除の操作をしても、現在の並べ替え方法とページ番号を維持するようにした。
ページ切り替えのリンクを上下に表示するようにした。
アップロードするCSVファイルサイズの制限を2MBに設定。
- app/models/csv.rb
- モデル
...(途中省略)... def validate_on_create errors.add(:file_size, "...ファイルが大き過ぎます。2MB以下でお願いします。") if @file && @file.size > 2*1024*1024 end # Tempfileオブジェクトをインスタンス変数に保存する。 # save()や、update_attributes()の時、呼び出される。 def tempfile=(file) return if file.nil? || file.size == 0 @file = file self.file_name = file.original_filename.gsub(/^(.)|\W/, '_\1') self.file_size = file.size end ...(途中省略)...
- app/views/csvs/_form.rhtml
- ビュー
<%= error_messages_for 'csv' %> <table class="csv_form"> <!--[form:csv]--> <tr> <% if ['new', 'create'].include?(controller.action_name) %> <th align="right" rowspan="2"><label for="csv_tempfile">ファイル:</label></th> <td <%= "class='fieldWithErrors'" if @csv.errors.on(:file_name) %>> <%= file_field 'csv', 'tempfile' %> <small> <%= "重複ファイル名: #{@csv.file_name}" if @csv.file_name && @csv.errors.on(:file_name) %> </small> </td>
不満な要素
- フラッシュメーセージを表示し続けるべきか?一定時間経過後に表示を隠したい。
- ファイル名の先頭が、_(アンダーバー)で始まっていることに気付き難い。だから「ファイル名が...で始まる」でフィルターしても、思うような結果が返らず、悩んでしまう。
- フィルターがセットされた状態で編集、削除を実行すると、フィルターが解除されてしまう。
- 現状は、ファイル名は重複してはならないので、時間を表現する名前と、内容を表現する名前を組み合わせて、ファイル名を命名する必要がある。お勧めは、時間情報、内容情報の順にファイル名を命名する方法。(並び替えは時間順に表示された方が便利な気がする。内容を絞り込みたい時は、フィルターを利用する。)
- しかし、異なる意味の情報は項目を分けるべきでもあり、アップロードした時に時間的情報を入力してもらい、内容情報と時間情報を組み合わせてデータベースに登録するという手段もある。この場合、以下のようなデメリットも発生する。
- 毎回、時間情報を入力するのが手間になる。
- 自分の保管するファイルと、アップロードしてあるファイルの対応が、分かり難くなる可能性がある。