active_scaffold と attachment_fu の併用

active_scaffold の内部で attachment_fu を動かす方法の解説。

Attachment というあらゆる種類のデータをアップするモデルを使うものとして解説します。

ファイルのアップロード

まずはコントローラ attachments_controller を編集します。

class AttachmentsController < ApplicationController
  active_scaffold :attachment do |config|
    # データをアップするためのフィールドを追加
    config.columns.add :uploaded_data
    # アップロードを行うので form を multipart に
    config.create.multipart = true
    # 各種フィールドは自動設定なので uploaded_data 以外必要ない
    config.create.columns = [:uploaded_data]
    # データの更新時も同じように処理する
    config.update.multipart = true
    config.update.columns = [:uploaded_data]
  end
end

以上。続いてアップロードを正しく行うためにヘルパを修正します。

module AttachmentsHelper
  def uploaded_data_form_column(record, input_name)
    file_field_tag input_name
  end
end

これでファイルをアップロードする準備は完了。

見た目の調整

アップロードはできるようになりましたが、これではどのデータが何なのか(特に画像)分かりづらいので表示を整えます。

まずはコントローラに一行追加。

class AttachmentsController < ApplicationController
  active_scaffold :attachment do |config|
    config.columns.add :uploaded_data
    config.create.multipart = true
    config.create.columns = [:uploaded_data]
    config.update.multipart = true
    config.update.columns = [:uploaded_data]
    # list アクションで表示されるカラムを設定
    config.list.columns = [:attachment]
  end
end

このカラムは Attachment には存在しませんが、ヘルパで定義する事で本来のカラムのように扱えます。ヘルパを更新します。

module AttachmentsHelper
  def uploaded_data_form_column(record, input_name)
    file_field_tag input_name
  end

  # ここから追加、カラム名_column(record) という形式でメソッドを作成
  def attachment_column(record)
    record.image? ? image_tag(record.public_filename) : record.filename
  end
end

アップされたデータが画像なら画像が、それ以外ならファイル名が表示されるようになりました。

補足、サムネイルの非表示

画像のサムネイルを作った場合、そちらまで表示されてしまい見栄えがよくありません。サムネイルは parent_id という値を持っているため parent_id がヌル値であるものだけを表示する事にします。

コントローラにメソッドを追加します。

class AttachmentsController < ApplicationController
  active_scaffold :attachment do |config|
    config.columns.add :uploaded_data
    config.create.multipart = true
    config.create.columns = [:uploaded_data]
    config.update.multipart = true
    config.update.columns = [:uploaded_data]
    config.list.columns = [:attachment]
  end

  # このメソッドで検索条件を設定できる
  def condition_for_collection
    ["parent_id IS ?", nil]
  end
end

ちなみに指定する条件は find の :conditions 句と同じ形式です。
条件を IS NULL と書かないのは私の趣味。万が一ヌル値が NULL でない DB があったら困るし、保守もめんどくさいから AR に投げられるだけ投げとこう、という発想。

参考

ActiveScaffold の公式サイトに同じような話が載っています。ただ、解説が少ないのと関連を使う前提なので注意。

http://wiki.activescaffold.com/wiki/published/ActiveScaffold+with+Attachment_fu