2012-03-15 38 views
10

Tôi đang cố gắng trừu tượng một số logic cần thiết để cắt xén hình ảnh thành một mô-đun để không làm rối loạn các mô hình của tôi. Mã này được dựa trên http://railscasts.com/episodes/182-cropping-imagesruby ​​bao gồm vs mở rộng

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 

Để đưa điều này vào mô hình của tôi có vẻ như rằng tôi phải sử dụng kéo dài. Tôi nghĩ mở rộng là để bao gồm các phương pháp lớp học. Tôi đến từ một nền tảng java - Tôi nghĩ rằng việc sử dụng mở rộng về cơ bản đã tạo ra phương thức tĩnh trên lớp.

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

- điều này làm việc

Có vẻ như sau đó những gì tôi đang thực sự mong muốn là tạo ra phương pháp dụ.

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

- Đây ném lỗi "phương pháp xác định 'croppable_image' cho #"

Bất cứ ai có xin giải thích whats going on và nếu tôi nên sử dụng bao gồm hoặc mở rộng trong trường hợp này. Thanks guys

+1

'extend' thêm các phương pháp như phương pháp lớp học, trong khi' include' thêm các phương pháp như phương pháp dụ. – zeacuss

Trả lời

13

extend M nội bộ cũng tương tự như class << self; include M; end - extend bao gồm mô-đun vào lớp singleton của một đối tượng (và làm cho các phương pháp thể hiện của các mô-đun là một phương pháp singleton của một lớp bạn mở rộng).

Trong trường hợp của bạn, bạn gọi croppable_imagetrong bối cảnh của một định nghĩa lớp và do đó croppable_image phải là một phương pháp thể hiện của một lớp Class hoặc một phương pháp singleton của Website lớp.

Đây là lý do tại sao bạn nên mở rộng Website lớp với một mô-đun CroppableImage bằng cách sử dụng mở rộng CroppableImage - nó bổ sung thêm phương pháp dụ croppable_image như một phương pháp singleton của Website lớp.

+0

Tôi nghĩ cuối cùng cũng có được nó. croppable_image là một phương thức lớp nhưng các phương thức được định nghĩa bằng phương thức define_method trở thành instance. Tôi chỉ đọc http://stackoverflow.com/questions/302789/can-i-define-method-in-rails-models và tất cả bây giờ đã có ý nghĩa hơn rất nhiều. Cảm ơn sự giúp đỡ của bạn – Nick

+0

@Nick, Có, 'define_method' được thực hiện trên lớp' Website' và 'define_method' thêm * các phương thức mẫu * của lớp' Trang web'. –

7

bạn có thể sử dụng cả hai logic cùng nhau. Ruby có callbacks cho mở rộng và bao gồm Ví dụ về sử dụng bao gồm callback

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

một cách khéo léo để làm điều đó;) – Aghyad

Các vấn đề liên quan