2011-09-06 30 views
16

Tôi muốn khô cạn một số mô hình bằng cách di chuyển phạm vi chia sẻ vào một mô-đun, một cái gì đó như:Phạm vi được chia sẻ qua mô-đun?

module CommonScopes 
    extend ActiveSupport::Concern 

    module ClassMethods 
    scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc") 
    end 
end 

Tôi cũng muốn tạo kỹ thuật chia sẻ rằng thử nghiệm các mô-đun. Thật không may khi tôi cố gắng bao gồm phạm vi được chia sẻ trong mô hình của mình, tôi nhận được:

undefined method `order' for CommonScopes::ClassMethods:Module 

Bất kỳ ý tưởng nào? Cảm ơn!

Trả lời

13

bạn có thể sử dụng instance_eval

module CommonScopes 
    extend ActiveSupport::Concern 

    def self.included(klass) 
    klass.instance_eval do 
     scope :ordered_for_display, order("#{self.to_s.tableize}.rank asc") 
    end 
    end 
end 
+0

Bây giờ bạn không nên nghĩ đến lambdas? – mdemolin

+0

@mdemolin Tôi tin rằng gọi 'scope' mà không có một lambda bị phản đối trong đường ray 4. – Gazler

+1

chính xác những gì tôi đã nói :) (nhưng tôi nghĩ rằng nó chỉ là cú pháp ưa thích cho bây giờ, và không bị phản đối chưa) – mdemolin

2

Bởi vì phương pháp scope của bạn được gọi ngay lập tức khi mô-đun của bạn được phân tách bởi Ruby và nó không thể truy cập từ mô-đun CommonScopes của bạn ..

Nhưng bạn có thể thay thế cuộc gọi phạm vi của bạn bằng một phương pháp học:

module CommonScopes 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def ordered_for_display 
     order("#{self.to_s.tableize}.rank asc") 
    end 
    end 
end 
37

Như trong đường ray 4 scope syntax bạn chỉ có thể sử dụng một lambda để trì hoãn việc thi hành mã (hoạt động trong đường ray 3 quá):

module CommonScopes 
    extend ActiveSupport::Concern 

    included do 
    scope :ordered_for_display, -> { order("#{self.to_s.tableize}.rank asc") } 
    end 
end 
+0

Đó là cách tốt hơn. –

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