2012-03-15 2 views
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 

에 따라 내가 연장 사용해야 할 것으로 보인다. 나는 클래스 메소드를 포함하기위한 확장이 있다고 생각했다. 나는 자바 배경에서입니다 - 클래스를 사용하여 기본적으로 확장 된 정적 메서드를 사용하여 확장 생각.

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

-이 내가 정말 걸려 라하는 인스턴스 메소드를 생성하는 것입니다 다음 보인다

작동합니다.

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

- 이것은 "#에 대한 정의되지 않은 메서드`croppable_image '"오류가 발생합니다

는 아무도 내가 포함하거나,이 경우 연장 사용 할 필요가있는 경우에 가서 무슨 설명해주십시오 수 있습니다. extend 객체의 단일 클래스에 모듈을 포함 (및 모듈의 인스턴스 메서드는 확장 클래스의 싱글 방법이 될 수 있습니다) -이 고마워

+1

'extend' 클래스 메소드와 방법을 추가 포함 콜백을 사용 실시 예를 포함한다. – zeacuss

답변

13

extend M 내부적으로 class << self; include M; end 유사하다. 귀하의 경우에는

당신은 클래스 정의의 맥락에서 croppable_image를 호출하여 croppable_imageClass 클래스의 인스턴스 방법 또는 Website 클래스의 싱글 방법이어야한다. 당신이 이 CroppableImage을 확장 사용하여 모듈 CroppableImageWebsite 클래스를 확장해야하는 이유

입니다 - 그것은 Website 클래스의 싱글 방법으로 인스턴스 메소드 croppable_image를 추가합니다.

+0

드디어 생각합니다. croppable_image는 클래스 메소드이지만 define_method로 정의 된 메소드는 인스턴스 메소드가됩니다. 방금 http://stackoverflow.com/questions/302789/can-i-define-method-in-rails-models을 읽었습니다. 이제 모든 것이 훨씬 더 의미가 있습니다. 당신의 도움을 주셔서 감사합니다 – Nick

+0

@Nick, 네,'define_method'는'Website' 클래스에서 실행되고'define_method'는'Website' 클래스의 * instance methods *를 추가합니다. –

7

두 로직을 함께 사용할 수 있습니다. 루비 대한 콜백을 갖는 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 
+0

매끄러운 방법;) – Aghyad