アップロードの管理機能を追加 その1
前回考えたアップロード管理の仕組みに合わせて、コードを追記してみた。
マイグレーションでデータベースの修正
- csvsテーブルに、以下のフィールドを追加した。
management_section_id | アップロードしたcsvファイルの管理部門 |
user_id | アップロードしたcsvファイルの担当者 |
editable | アップロードしたcsvファイルの内容を編集可能かどうか |
# ---------- db/migrate/004_add_column_managed_section_uploader_readonly.rb ---------- class AddColumnManagedSectionUploaderReadonly < ActiveRecord::Migration def self.up add_column :csvs, :management_section_id, :integer add_column :csvs, :user_id, :integer add_column :csvs, :editable, :boolean end def self.down remove_column :csvs, :management_section_id remove_column :csvs, :user_id remove_column :csvs, :editable end end
- management_sectionsテーブルと、usersとの多:多関連のため中間テーブルを追加した。
# ---------- db/migrate/005_create_management_sections.rb ---------- class CreateManagementSections < ActiveRecord::Migration def self.up create_table :management_sections do |t| t.column :name, :string end # id列が不要な場合は、:id => false とオプション指定する。 create_table :management_sections_users, :id => false do |t| t.column :management_section_id, :integer t.column :user_id, :integer end end def self.down drop_table :management_sections drop_table :management_sections_users end end
モデル間の関連を設定
- app/models/フォルダのファイル
class Csv < ActiveRecord::Base belongs_to :user belongs_to :management_section class ManagementSection < ActiveRecord::Base has_and_belongs_to_many :users has_many :csvs class Path < ActiveRecord::Base has_and_belongs_to_many :users class User < ActiveRecord::Base has_and_belongs_to_many :paths has_and_belongs_to_many :management_sections has_many :csvs
-
-
- 多:多関連の中間テーブルは省略した。
- login_engine、user_engineの属性も省略した。
-
new、editアクションに関係する変更
コントローラー
- @sections = session[:user].management_sectionsで、ユーザーが所有するmanagement_sectionの配列が代入される。collection_selectでプルダウンリストを表示する時に利用する。
# ---------- app/controllers/csvs_controller.rb ---------- ...(途中省略)... def new # ログインユーザーをアップロード担当者にする。new(:user_id => session[:user].id) @csv = Csv.new(:user_id => session[:user].id) @sections = session[:user].management_sections end def create @csv = Csv.new(params[:csv]) @sections = session[:user].management_sections if @csv.save ...(途中省略)... end def edit @csv = Csv.find(params[:id]) @sections = session[:user].management_sections end def update @csv = Csv.find(params[:id]) @sections = session[:user].management_sections if @csv.update_attributes(params[:csv]) ...(途中省略)... end
ビュー
- CSVファイルをアップロードする時(new、createアクションの時)は、ファイル選択フィールドを表示する。
- CSVファイルの属性を編集する時(edit、updateアクションの時)は、テキストフィールドでファイル名だけ表示する。
<%# ---------- app/views/csvs/_form.rhtml ---------- %> <%= error_messages_for 'csv' %> <table> <!--[form:csv]--> <tr> <% if ['new', 'create'].include?(controller.action_name) %> <th align="right"><label for="csv_tempfile">ファイル:</label></th> <td><%= file_field 'csv', 'tempfile' %></td> <% else %> <th align="right"><label for="csv_file_name"><b>ファイル:</label></th> <td><%= text_field 'csv', 'file_name', :disabled => true %></td> <% end %> </tr> <tr> <th></th> <td><%= check_box 'csv', 'editable' %>編集可能</td> </tr> <tr> <th align="right"><label for="csv_file_comment">コメント:</label></th> <td><%= text_field 'csv', 'file_comment' %></td> </tr> <tr> <th align="right"><label for="csv_management_section_id"><b>管理部門:</label></th> <td><%= collection_select :csv, :management_section_id, @sections, :id, :name %></td> </tr> <tr> <th align="right"><label for="csv_user_id">アップロード担当者:</label></th> <td><%= text_field_tag 'csv_user_id', @csv.user.fullname, :disabled => true %> <%#= :disabled => true を指定すると、パラメーターも送信されないため、hidden_fieldを利用 %> <%= hidden_field 'csv', 'user_id' %></td> </tr>
listアクションに関係する変更
ビュー
- ユーザーが所有する権限によって、アクションのリンクを表示、非表示、リンクなし、の状態に変化するようにした。
- admin?、uploader?、management_section?は、app/helpers/フォルダ内に定義したメソッド。application_helper.rbに定義しておいたので、csv_serverプロジェクトのビューであれば、どこからでも呼び出すことが出来る。
<%# ---------- app/views/csvs/_listd.rhtml ---------- %> <!--[:]--> <tr> <%# リストデータの表示 %> <!--<td><%=h listd.id %></td>--> <td><%= link_to h(listd.file_name), :controller => 'displays', :action=>'list', :table => listd.csv_table %></td> <td><%=h listd.file_comment %></td> <td><%= listd.editable ? "編集可能" : "表示のみ" %></td> <td align="right"><%=h listd.file_size.to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, '\1,') %> B</td> <td><%=h listd.created_at.strftime('%Y/%m/%d %H:%M:%S') %></td> <td><%=h listd.file_updated_at.strftime('%Y/%m/%d %H:%M:%S') if listd.file_updated_at %></td> <td><%=h listd.management_section.name if listd.management_section_id > 0 %></td> <td><%=h listd.user.fullname if listd.user_id > 0 %></td> <%# 詳細 編集 削除のアクションを表示 %> <%# ユーザーが所有する権限によって、表示 非表示 リンク設定なし に状態を変更する。 %> <% if admin? %> <td class="action" align="center"> <%= link_to '詳細', :action => 'show', :id => listd %></td> <% end %> <% if admin? || uploader? %> <td class="action" align="center"> <%= link_to_if management_section?(listd.management_section), '編集', :action => 'edit', :id => listd %></td> <td class="action" align="center"> <%= link_to_if management_section?(listd.management_section), '削除', { :action => 'destroy', :id => listd }, :confirm => _('Are you sure?'), :post => true %></td> <% end %> </tr> <!--[:]-->
ヘルパ
- ここで定義したメソッドは、ビューから関数を利用するように呼び出すことが出来る。
- モデル名と同じ名前_helper.rb のファイルに定義すると、そのモデルのビュー限定のメソッドになる。
- application_helper.rb に定義すると、全てのビューから呼び出すことが出来る。
# ---------- app/helpers/application_helper.rb ---------- # Methods added to this helper will be available to all templates in the application. module ApplicationHelper ...(途中省略)... # ログインユーザーが、admin権限ならtrueを返す。 def admin? session[:user].admin? if session[:user] end # ログインユーザーが、Uploader権限ならtrueを返す。 def uploader? session[:user].roles.each { |r| return true if r.name == 'Uploader' } false end # ログインユーザーが、csv_sectionで渡された、管理部門に所属していればtrueを返す。 def management_section?(csv_section) return true if session[:user].management_sections.include?(csv_section) || csv_section.nil? || admin? false end