10

モデルを台無しにしないように、画像をモジュールにトリミングするために必要なロジックの一部を抽象化しようとしています。コードはhttp://railscasts.com/episodes/182-cropping-imagesに基づいています

module CroppableImage
  def croppable_image(*image_names)
    image_names.each do |image_name|

      define_method "#{image_name}_sizes" do
        { :cropped => read_attribute("#{image_name}_size").to_s, :large => "800x800>" }
      end

      define_method "#{image_name}_geometry" do |style|
        style ||= :original
        @geometry ||= {}
        @geometry[style] ||= Paperclip::Geometry.from_file(eval "#{image_name}.path(style)")
      end

      define_method "#{image_name}_aspect_ratio" do
        width, height = read_attribute("#{image_name}_size").split("x")
        width.to_f / height.to_f
      end

      private

        define_method "reprocess_#{image_name}" do
          eval "#{image_name}.reprocess!"
        end

    end
  end

end

これをモデルに含めるには、extend を使用する必要があるようです。拡張はクラスメソッドを含めるためのものだと思いました。私はJavaのバックグラウンドから来ました-クラスで基本的に作成された静的メソッドを拡張することを考えました。

class Website < ActiveRecord::Base
  extend CroppableImage
  croppable_image :logo, :footer_image

-- これは動作します

私が本当に望んでいるのは、インスタンスメソッドを作成することです。

class Website < ActiveRecord::Base
  include CroppableImage
  croppable_image :logo, :footer_image

-- これにより、「未定義のメソッド `croppable_image' for #」というエラーがスローされます。

この場合、何が起こっているのか、インクルードまたはエクステンドを使用する必要があるかどうかを説明してください。みんなありがとう

4

2 に答える 2

14

extend M内部的にはclass << self; include M; end-extendモジュールをオブジェクトのシングルトン クラスにインクルードします (モジュールのインスタンス メソッドを、拡張するクラスのシングルトン メソッドにします)。

あなたの場合croppable_image 、クラス定義のコンテキストで呼び出すため、クラスのインスタンスメソッドまたはクラスのシングルトンメソッドであるcroppable_image必要があります。ClassWebsite

これが、extend CroppableImageを使用Websiteしてモジュールでクラスを拡張する必要がある理由です。インスタンス メソッドをクラスのシングルトン メソッドとして追加します。CroppableImagecroppable_imageWebsite

于 2012-03-15T08:17:11.267 に答える
7

両方のロジックを一緒に使用できます。Ruby には extends と include のコールバックがあります include コールバックの使用例

module CroppableImage
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def bar
      puts 'class method'
    end
  end

  def foo
    puts 'instance method'
  end
end
于 2012-03-15T08:32:20.070 に答える