2012-07-24 32 views
5

Tôi có một tập tin trong thư mục lib có sử dụng một số các hằng số được định nghĩa trong một mô hình, như:mô hình truy cập từ bên trong thư mục lib trong một dự án Rails 3

class User < ActiveRecord::Base 
    MAX_EMAIL_ADDRESS_LENGTH = 255 
end 

và sau đó tôi có trong lib/foo. rb

module Foo 
    LONG_EMAIL_ADDRESS = "[email protected]".rjust(User::MAX_EMAIL_ADDRESS_LENGTH, "a") 
end 

Không thành công do không tìm được người dùng hạng. Làm thế nào tôi có thể tải Người dùng trước tệp đó trên lib?

Tôi đang tải tập tin đó bằng cách này trong application.rb tôi:

config.autoload_paths += %W(#{config.root}/lib) 
+0

How are you bao gồm 'lib' trong ứng dụng ray của bạn ? Trong đường ray 3, nó không được tự động nạp theo mặc định, vì vậy cho thấy cách bạn đang truy cập vào 'lib/foo.rb' sẽ hữu ích. – deefour

+0

@Deefour, xong. – Pablo

+0

Bạn có bao gồm mô-đun này không? Nếu vậy, nó được bao gồm ở đâu? –

Trả lời

2

Giải pháp là tệp của tôi trong/lib thực sự được yêu cầu bởi tệp rake và có vẻ tệp được tải trước khi toàn bộ hệ thống tải tự động được thiết lập bởi Rails, vì vậy không thể tìm thấy ngươi mâu. Sau khi tôi xóa yêu cầu khỏi tệp .rake, mọi thứ bắt đầu hoạt động.

1

Theo mặc định, YourApplicationNameHere::Application.autoload_paths[]. Tôi (hoàn toàn vì lý do tổ chức) thêm hình cầu cho thư mục app/models của tôi.

config.autoload_paths += Dir["#{Rails.root}/app/models/**/"] 
config.autoload_paths += Dir["#{config.root}/lib"] 

Với thiết lập này, tôi có thể thực hiện những gì bạn đang hỏi trong Câu hỏi mà không gặp sự cố. Điều này cũng sẽ mang lại lợi ích cho bạn, hãy nói cho Rails biết địa điểm nào nếu không thể tìm thấy mô hình User từ trong instantiation lib/ của mô-đun.

Sửa

Xác định được thông báo lỗi chính xác trong câu hỏi của bạn đã có thể giúp quá.

uninitialized constant Foo::User 

nghĩa Ruby/Rails đang tìm kiếm User trong namespace Foo. Tiền tố User với :: để bắt buộc tra cứu không gian tên chung.

module Foo 
    LONG_EMAIL_ADDRESS = "[email protected]".rjust(::User::MAX_EMAIL_ADDRESS_LENGTH, "a") 
end 
+0

Điều đó không hiệu quả đối với tôi. Tôi đã thử một số biến thể và tôi luôn kết thúc với: uninitialized constant Foo :: User. – Pablo

+0

Vui lòng xem chỉnh sửa của tôi. – deefour

0

Có vẻ như lớp học của bạn chưa được khởi tạo, điều này có vẻ bất thường, trừ khi bạn có 'user.rb' ở một vị trí không phải là 'mô hình'. Nó thường là trường hợp các lớp không được phát triển trừ khi chúng nằm trong thư mục đó, nhưng một giải pháp tôi sử dụng là dòng này mà bạn có thể đặt ngay bên trong mã mà bạn mong muốn được gọi trước dòng vi phạm mà bạn có ..

Rails.application.eager_load! if Rails.env == "development" 

Phần có điều kiện có thể là không cần thiết, nhưng tôi đưa nó vào để chắc chắn hiệu ứng của nó chỉ xảy ra trong quá trình phát triển.

1

Phần đầu tiên đã được thực hiện đúng:

config.autoload_paths += %W(#{config.root}/lib) 

Tiếp theo, điều quan trọng là, mô-đun

module Foo 
    ... 
end 

phải được đặt vào

lib/foo.rb 

tập tin.

Và sau đó, có thể là include d vào mã ứng dụng.

class Comment < ActiveRecord::Base 
    include Foo 
    ... 
end 

Nếu tập tin foo.rb từ thư mục lib không có ý định để được bao gồm (tuy nhiên nó có lẽ là một cách sai lầm), sau đó sử dụng mô hình Rails và các công cụ khác bên trong mã này bạn nên đặt này vào foo.rb:

require_relative "../config/environment.rb" 
+0

Tôi không cố gắng truy cập vào một lib từ một mô hình, mà là một mô hình từ một tệp lib. – Pablo

+0

Vì vậy, hãy thử 'require_relative" ../ config/environment.rb "' –

2

Tôi biết đây là câu hỏi cũ nhưng tôi chỉ gặp phải vấn đề tương tự và sau một số tìm kiếm, tôi đã tìm thấy giải pháp vì vậy tôi cho rằng nên chia sẻ nó.

Tôi muốn sử dụng mô hình "Foo" trong một tệp được yêu cầu nằm trong thư mục/lib của tôi. Đầu tiên, tôi đã làm điều này và nó không hoạt động:

# in my rake file 
task :foo_task do 
    require /some_path/lib/bar.rb 
end 

# in /lib/bar.rb 
puts "Foo = #{Foo.count} " 

# => uninitialized constant Foo 

Sau khi tìm kiếm, tôi cần xác định môi trường trong tác vụ của mình. Vì vậy, tôi chỉ cần thêm này để tuyên bố nhiệm vụ của tôi:

task :foo_task => [:environment] do 

Bây giờ, khi tôi gọi nhiệm vụ của tôi, nó đúng đặt số lượng Foo:

# => Foo = 6 
Các vấn đề liên quan