7

これは私の画像モデルで、添付ファイルの寸法を検証するメソッドを実装しています:

class Image < ActiveRecord::Base
  attr_accessible :file

  belongs_to :imageable, polymorphic: true

  has_attached_file :file,
                     styles: { thumb: '220x175#', thumb_big: '460x311#' }

  validates_attachment :file,
                        presence: true,
                        size: { in: 0..600.kilobytes },
                        content_type: { content_type: 'image/jpeg' }

  validate :file_dimensions

  private

  def file_dimensions(width = 680, height = 540)
    dimensions = Paperclip::Geometry.from_file(file.queued_for_write[:original].path)
    unless dimensions.width == width && dimensions.height == height
      errors.add :file, "Width must be #{width}px and height must be #{height}px"
    end
  end
end

これは問題なく動作しますが、メソッドは幅と高さの固定値を取るため、再利用できません。これを Custom Validator に変換したいので、他のモデルでも使用できます。これについてのガイドを読みましたが、app/models/dimensions_validator.rb で次のようになることを知っています。

class DimensionsValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    dimensions = Paperclip::Geometry.from_file(record.queued_for_write[:original].path)

    unless dimensions.width == 680 && dimensions.height == 540
      record.errors[attribute] << "Width must be #{width}px and height must be #{height}px"
    end
  end
end

しかし、このコードが機能しないために何かが足りないことはわかっています。問題は、モデルで次のように検証を呼び出したいということです。

validates :attachment, dimensions: { width: 300, height: 200}.

このバリデーターをどのように実装する必要があるかについて何か考えはありますか?

4

2 に答える 2

19

これを app/validators/dimensions_validator.rb に入れます:

class DimensionsValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    # I'm not sure about this:
    dimensions = Paperclip::Geometry.from_file(value.queued_for_write[:original].path)
    # But this is what you need to know:
    width = options[:width]
    height = options[:height] 

    record.errors[attribute] << "Width must be #{width}px" unless dimensions.width == width
    record.errors[attribute] << "Height must be #{height}px" unless dimensions.height == height
  end
end

次に、モデルで:

validates :file, :dimensions => { :width => 300, :height => 300 }
于 2012-09-12T13:15:53.730 に答える