AR を使わない validation (ファイルアップロードのサンプル)
Form に1対1で対応するモデル(?) ActionForm を使ってみた。
インストール方法は、こちら→京の路|RailsのActiveFormの使い方
class HogeFile < ActiveForm attr_accessor :name, :type, :size, :data validates_format_of :type, :with => /^text/, :message => 'テキスト形式のファイルを選択して下さい' validates_each :size do |recode, attr, value| message = ''; if value.blank? || value.to_i <= 0 then message = 'ファイルを選択して下さい (ファイルを選択しても、このメッセージが表示される場合は、ファイルのサイズが 0 ではない事を、ご確認下さい)' elsif 5_000_000 < value.to_i then message = 'サイズが 5M 以下のファイルを選択して下さい' end recode.errors.add attr, message if !message.blank? end def file=(file) self.name = File.basename(file.original_filename).gsub(/^?w._-/, '') ? if file.respond_to?(:original_filename) self.type = file.content_type.chomp if file.respond_to?(:content_type) self.size = file.size if file.respond_to?(:size) self.data = file.read if file.respond_to?(:read) end def save File.open('tmp/uploads/' + self.name, 'wb') do |f| f.write(self.data) end end end
ActiveForm を plugin 配下に設置してしまえば、model 内で即継承可能。(require 不要)
attr_accessor でアクセサを作って、validates_xxx_of で値の検証を行える。
ファイルはフォームから、@params[:hoge][:file] として入ってくるように作るので
file= メソッドを定義して、プロパティの初期化を行っている。
(この辺りの説明は、ActiveForm の source 読んだ方が早い)
class HogeController < ApplicationController def index @hoge_file = HogeFile.new if @hoge_file.nil? # do something.. end def upload @hoge_file = HogeFile.new( params[:hoge] ) if @hoge_file.valid? then @hoge_file.save else index render :action => 'index' end end end
「index」 呼んで「render :action => 'index'」してるのがダサい。
<%= error_messages_for :hoge_file %> <%= form_tag({:action => 'upload'}, {:multipart => true}) %> <%= file_field :hoge, :file %> <%= submit_tag 'upload' %> <%= end_form_tag %>
error_messages_for を使いたいが為に、HogeController#index で「@hoge_file」の初期化を行っている。ダサい。
全体的に、勉強不足。rails 熟練者の方に、美しい書き方をご指導願いたいなぁ・・・。