2013-05-15 29 views
8

Tôi đã sau thiết lập:Yêu cầu phụ thuộc để có được Rails lớp con

app/models/my_module/service.rb

module MyModule 
    class Service < ActiveRecord::Base 
    def self.types 
     self.subclasses 
    end 

    def self.raw_types 
     self.types.map { |c| c.name.split("::").last } 
    end 
    end 
end 

require_dependency "my_module/service/rack" 
require_dependency "my_module/service/rails" 
require_dependency "my_module/service/sinatra" 

app/models/my_module/dịch vụ/rack.rb:

module MyModule 
    class Service::Rack < Service 
    end 
end 

app/models/my_module/dịch vụ/rails.rb:

module MyModule 
    class Service::Rails < Service 
    end 
end 

app/models/my_module/dịch vụ/sinatra.rb:

module MyModule 
    class Service::Sinatra < Service 
    end 
end 

đó làm việc cho đến nay, nhưng bây giờ câu hỏi của tôi:

Tại sao tôi phải thêm ba dòng:

require_dependency "my_module/service/rack" 
require_dependency "my_module/service/rails" 
require_dependency "my_module/service/sinatra" 

vào tệp service.rb của tôi?

Nếu tôi không thêm ba dòng:

MyModule::Service.raw_types 
=> [] 

Nếu tôi thêm ba dòng:

MyModule::Service.raw_types 
=> ["Rack", "Rails", "Sinatra"] 

Bất kỳ ai một ý tưởng?

Btw: Tôi sử dụng Ruby 2.0.0-preview1, Rails 4.0.0.rc1 và tạo một công cụ Rails mới với

rails plugin new MyModule 
+0

Liệu MyModule :: Service.types làm việc? –

+0

Là câu hỏi tại sao phải yêu cầu các tập tin hoặc lý do tại sao mảng được dân cư? Khi bạn yêu cầu các tệp bạn thêm 3 lớp mà tất cả các dịch vụ phân lớp, do đó 'Service.subclasses' trả về 3 lớp đó. – Kris

+0

Ý tưởng: một trong những tập tin con khỉ-bản vá lỗi 'lớp con' vào lớp. – User

Trả lời

12

Theo mặc định, trong môi trường phát triển, Rails sẽ tự động load hằng trong thông thường thư mục con của app, bằng cách tìm kiếm địa điểm thông thường (ví dụ: /app/models/my_module/service/rack.rb cho MyModule::Service::Rack). Tự động tải này xảy ra khi hằng số được tham chiếu lần đầu tiên, không phải khi khởi chạy ứng dụng.

Nhưng điều này có nghĩa là trước khi hằng số được tham chiếu, tệp xác định nó không được tải trừ khi được yêu cầu rõ ràng.

Do đó, khi bạn gọi MyModule::Service.raw_types, MyModule::Service được tải từ app/models/my_module/service.rb nếu chưa được xác định. Tuy nhiên, nếu không có tham chiếu nào chưa được thực hiện cho các lớp con của nó, các hằng số đó sẽ không được xác định trừ khi các tệp xác định chúng được yêu cầu một cách rõ ràng. Do đó, yêu cầu các tệp đó trong tệp mà được tự động tải về trên cuộc gọi phương thức đó làm cho chúng khả dụng.

đạo đức: nếu bạn muốn đảm bảo rằng các lớp con của MyModule::Service luôn được xác định bất cứ khi nào MyModule::Service là, bạn cần phải yêu cầu họ trong /app/models/my_module/service.rb

+0

Được rồi tôi đã nghĩ, nhưng tôi hy vọng, Rails sửa chữa tự động tải trong khi phương thức được gọi, bởi vì các lớp là cần thiết thông qua một cuộc gọi phương thức lớp cha .. nó có thể là một lỗi Rails? Tôi hiểu việc tải từ một "dạng xem ruby", nhưng không phải từ "chế độ xem đường ray" .. – Mattherick

+2

Đây không phải là lỗi trong Rails. Ứng dụng phải biết rằng các hằng số đó là cần thiết khi nó thậm chí không biết chúng tồn tại? Tôi không nghĩ rằng có bất kỳ tác hại nào trong việc yêu cầu các lớp con của bạn trong tệp định nghĩa lớp cha. Ngoài ra, bạn có thể tải tất cả chúng trong config/boot.rb để chúng có thể khởi chạy ứng dụng. – gregates

+0

Nhưng nó sẽ thực sự tốt, nếu Rails có một hành vi như vậy mà nó tìm kiếm thư mục con được gọi là module xung quanh lớp cha để kiểm tra xem có các lớp con được định nghĩa hay không. Điều đó sẽ tuyệt vời :). Nhưng dù sao tôi chỉ sẽ tải chúng tất cả thông qua quá trình khởi tạo đường ray. – Mattherick

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