2012-11-05 27 views
6

Tôi có hai không gian tên, mỗi bộ điều khiển và người dẫn chương trình của riêng lớp của nó: Member::DocumentsController Member::DocumentPresenter Guest::DocumentsController Guest::DocumentPresenterRails lớp bốc bỏ qua namespaced lớp khi một lớp cùng tên trong không gian tên gốc được nạp

Cả hai thuyết trình kế thừa từ ::DocumentPresenter.

điều khiển truy cập thuyết trình của mình mà không gian tên cụ thể, ví dụ .:

class Guest::DocumentsController < ActionController::Base 
    def show 
     DocumentPresenter.new(find_document) 
    end 
end 

này thường gọi là người dẫn chương trình trong cùng một không gian tên. Tuy nhiên đôi khi trong môi trường phát triển tôi thấy cơ sở :: DocumentPresenter đang được sử dụng.

Tôi nghi ngờ nguyên nhân là cơ sở đó :: DocumentPresenter đã được tải, do đó việc tự động tải lớp Rails không bận tâm để xem xét thêm. Đây có phải là trường hợp? Nó có thể xảy ra trong môi trường sản xuất không?

tôi có thể nghĩ ra hai giải pháp:

  • đổi tên lớp cơ sở để DocumentPresenterBase
  • đòi hỏi một cách rõ ràng các file người dẫn chương trình thích hợp trong các tập tin điều khiển

Có một giải pháp tốt hơn?

+2

Nếu bạn đang 'show' phương thức bên trong' Guest :: DocumentsController' sẽ chỉ làm việc với 'Guest :: DocumentPresenter' nó sẽ được đơn giản nhất để xác định không gian tên khi gọi nó là' mới' phương pháp. – deefour

+0

@ Deefour haha ​​yes Tôi quên mất điều hiển nhiên nhất - cảm ơn. Tôi sẽ đợi một lúc để có một giải pháp hoàn hảo, điều này sẽ không khiến tôi thêm các ký tự trên tất cả các tệp nguồn của mình. –

+1

Chỉ AFAIK Rails preloads Mô hình trong 'production' vì vậy điều này cũng xảy ra trong quá trình sản xuất (nhưng tôi không thể tìm thấy tài liệu thực tế trên máy ATM này). – Laas

Trả lời

3

Bạn đúng trong các giả định của mình - Nếu bạn không chỉ định không gian tên, Ruby bắt đầu từ không gian tên hiện tại và thực hiện theo cách của mình để tìm lớp và vì lớp không được tự động tải, ::DocumentPresenter được tìm thấy và trình nạp tự động không kích hoạt.

Là một giải pháp Tôi muốn giới thiệu đổi tên ::DocumentPresenter để DocumentPresenterBase, bởi vì đây bảo vệ bạn khỏi các lỗi khi bạn quên namespacing hoặc rõ ràng đòi hỏi nơi nào đó.

Tùy chọn thứ hai thứ hai để xem xét thực sự sẽ sử dụng các tên lớp cụ thể trên toàn bộ địa điểm, nhưng điều này bị lỗi khi bạn vô tình quên không gian tên một số cuộc gọi.

class Guest::DocumentsController < ActionController::Base 
    def show 
    Guest::DocumentPresenter.new(find_document) 
    end 
end 

Thứ ba tùy chọn sẽ là thứ hai của bạn - đòi hỏi một cách rõ ràng tất cả các lớp trong initializer trước. Tôi đã làm điều này với Rails API nhận các mô hình nhúng trong JSON và Rails có xu hướng không gian tên chúng khi các mô hình thực tế chưa được tải.

Lựa chọn 3,5 Bạn có thể có thể lừa autoloader để làm các việc nâng nặng (tuy nhiên, điều này có vẻ giống như một hack):

class Guest::DocumentsController < ActionController::Base 

    # trigger autoload 
    Guest::DocumentPresenter 

    def show 
    # This should refer Guest::DocumentPresenter 
    DocumentPresenter.new(find_document) 
    end 

    def show 
    # As will this 
    DocumentPresenter.new(find_document) 
    end 
end 

Vẫn là sạch sẽ được đổi tên lớp cơ sở.

1

Tôi nghĩ rằng trong 3 giải pháp nếu bạn muốn mantein tên, một là giải pháp thứ hai của bạn.

1) đòi hỏi một cách rõ ràng các file người dẫn chương trình thích hợp trong các tập tin điều khiển

2) Thực hiện các đường dẫn lớp môi trường đầy đủ, như:

class Guest::DocumentsController < ActionController::Base 
    def show 
     Guest::DocumentPresenter.new(find_document) 
    end 
end 

3) Tạo một file trên thư mục khởi tạo và thực hiện yêu cầu bằng tay (các tùy chọn tồi tệ nhất: S)

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