2014-11-16 17 views
7

Có cách nào để sử dụng đối số khi đưa mô-đun ruby ​​không? Tôi có một tài sản mô-đun được bao gồm trong nhiều lớp. Tôi muốn có thể tạo ra attr_accessor khi đang bay.Ruby on Rails, bao gồm mô-đun có đối số

module Assetable 
    extend ActiveSupport::Concern 

    included do 
    (argument).times do |i| 
     attr_accessor "asset_#{i}".to_sym 
     attr_accessible "asset_#{i}".to_sym 
    end 
    end 
end 

Trả lời

13

Không có cách nào để chuyển đối số khi bao gồm mô-đun. Điều tiếp theo tốt nhất là để xác định một phương pháp học cho phép bạn tạo những gì bạn cần sau đó:

module Assetable 
    extend ActiveSupport::Concern 
    module ClassMethods 
    def total_assets(number) 
     number.times do |i| 
     attr_accessor "asset_#{i}" 
     attr_accessible "asset_#{i}" 
     end 
    end 
    end 
end 

class C 
    include Assetable 
    total_assets 3 
end 

o = C.new 
o.asset_2 = "Some value." 
o.asset_2 #=> "Some value." 

Cũng phải cẩn thận khi trọng phương pháp included trong một mối quan tâm vì nó cũng được sử dụng bởi ActiveSupport::Concern. Bạn nên gọi super trong phương pháp được ghi đè để đảm bảo khởi tạo đúng.

+0

cảm ơn, bạn nên gọi siêu ở đâu? – user3868832

+0

Chỉ khi bạn xác định một móc 'bao gồm' trong mối quan tâm, đó không phải là trường hợp với việc thực hiện này. –

4

Bạn không thể chuyển đối số cho mô-đun. Trong thực tế, bạn không thể chuyển đối số cho bất cứ điều gì ngoại trừ một tin nhắn gửi đi.

Vì vậy, bạn phải sử dụng một gửi thông điệp:

module Kernel 
    private def Assetable(num) 
    @__assetable_cache__ ||= [] 
    @__assetable_cache__[num] ||= Module.new do 
     num.times do |i| 
     attr_accessor :"asset_#{i}" 
     attr_accessible :"asset_#{i}" 
     end 
    end 
    end 
end 

class Foo 
    include Assetable 3 
end 

Lưu ý:. Tôi không thấy lý do tại sao bạn sẽ cần ActiveSupport::Concern đây ở tất cả, nhưng nó dễ dàng để thêm trở lại trong

+1

Cảm ơn, tôi đã thực hiện câu trả lời của Gabriel de Oliveira. Các chuyên gia và con của mỗi giải pháp là gì? – user3868832

13

Có là một thủ thuật: tạo một lớp kế thừa từ một mô-đun để bạn có thể chuyển bất kỳ đối số nào cho mô đun như lớp.

class Assetable < Module 
    def initialize(num) 
    @num = num 
    end 

    def included(base) 
    num = @num 

    base.class_eval do 
     num.times do |i| 
     attr_accessor "asset_#{i}" 
     end 
    end 
    end 
end 

class A 
    include Assetable.new(3) 
end 

a = A.new 
a.asset_0 = 123 
a.asset_0 # => 123 

Chi tiết được viết blog tại http://kinopyo.com/en/blog/ruby-include-module-with-arguments, hy vọng bạn sẽ thấy nó hữu ích.

+0

Chết tiệt, con trai! Giải pháp tốt. – henrebotha