Tôi biết đã lâu rồi kể từ lần đầu tiên câu hỏi này được hỏi, nhưng tôi có một câu trả lời bổ sung mà tôi muốn chia sẻ.
Tôi có một số ứng dụng Ruby được phát triển bởi một lập trình viên khác trong vài năm và chúng sử dụng lại các lớp giống nhau trong các ứng dụng khác nhau mặc dù chúng có thể truy cập cùng một cơ sở dữ liệu. Vì điều này vi phạm quy tắc DRY, tôi quyết định tạo một thư viện lớp để tất cả các ứng dụng Ruby chia sẻ. Tôi có thể đã đặt nó trong thư viện Ruby chính, nhưng điều đó sẽ ẩn mã tùy chỉnh trong cơ sở mã chung mà tôi không muốn làm.
Tôi đã gặp sự cố trong đó tôi có xung đột tên giữa tên đã được xác định "profile.rb" và lớp tôi đang sử dụng. Xung đột này không phải là vấn đề cho đến khi tôi cố gắng tạo thư viện mã chung. Thông thường, Ruby tìm kiếm các vị trí ứng dụng trước, sau đó đi đến các vị trí $ LOAD_PATH.
Application_controller.rb không thể tìm thấy lớp tôi đã tạo và gây ra lỗi cho định nghĩa ban đầu vì nó không phải là một lớp. Vì tôi đã xóa định nghĩa lớp khỏi phần ứng dụng / mô hình của ứng dụng, nên Ruby không thể tìm thấy nó ở đó và đã tìm kiếm nó trong các đường dẫn của Ruby.
Vì vậy, tôi đã sửa đổi biến $ LOAD_PATH để bao gồm một đường dẫn đến thư mục thư viện mà tôi đang sử dụng. Điều này có thể được thực hiện trong tệp môi trường.rb tại thời điểm khởi tạo.
Ngay cả khi thư mục mới được thêm vào đường dẫn tìm kiếm, Ruby vẫn gặp lỗi vì nó đã ưu tiên lấy tệp do hệ thống xác định trước. Đường dẫn tìm kiếm trong biến $ LOAD_PATH ưu tiên tìm kiếm các đường dẫn Ruby trước.
Vì vậy, tôi cần thay đổi thứ tự tìm kiếm để Ruby tìm thấy lớp trong thư viện chung của tôi trước khi nó tìm kiếm các thư viện tích hợp sẵn.
Mã này đã thực hiện nó trong tệp môi trường.rb:
Rails::Initializer.run do |config|
* * * * *
path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)
* * * * *
end
Tôi không nghĩ rằng bạn có thể sử dụng bất kỳ cấu trúc mã hóa nâng cao nào được đưa ra trước đó ở cấp độ này, nhưng nó hoạt động tốt nếu bạn muốn thiết lập thứ gì đó tại thời điểm khởi tạo trong ứng dụng của mình. Bạn phải duy trì thứ tự ban đầu của biến $ LOAD_PATH ban đầu khi nó được thêm trở lại biến mới nếu không một số lớp Ruby chính sẽ bị mất.
Trong tệp application_controller.rb, tôi chỉ cần sử dụng
require 'profile'
require 'etc' #etc
và điều này sẽ tải các tệp thư viện tùy chỉnh cho toàn bộ ứng dụng, tức là tôi không phải sử dụng các lệnh request trong mọi bộ điều khiển.
Đối với tôi, đây là giải pháp tôi đang tìm kiếm và tôi nghĩ rằng tôi sẽ thêm nó vào câu trả lời này để truyền thông tin.
File.expand_path(File.dirname(__FILE__)).tap {|pwd| $LOAD_PATH.unshift(pwd) unless $LOAD_PATH.include?(pwd)}