2012-12-28 30 views
56

Làm thế nào chúng ta có thể khởi tạo lớp từ chuỗi tên của nó trong Ruby-on-Rails?Làm thế nào để khởi tạo lớp từ chuỗi tên trong Rails?

Ví dụ: chúng tôi có tên trong cơ sở dữ liệu ở định dạng như "ClassName" hoặc "my_super_class_name".

Cách chúng tôi có thể tạo đối tượng từ nó?

Giải pháp:

Đang tìm kiếm bản thân mình, nhưng không tìm thấy, vì vậy ở đây nó được. Ruby-on-Rails API Method

name = "ClassName" 
instance = name.constantize.new 

Có thể thậm chí không được định dạng, chúng ta có thể sử dụng chuỗi phương pháp .classify

name = "my_super_class" 
instance = name.classify.constantize.new 

Tất nhiên có lẽ đây không phải là rất 'Rails cách', nhưng nó giải quyết mục đích của nó.

+4

Chỉ cần FYI, hằng số là một phương thức tiện lợi ActiveSupport mà 'Object.const_get' và Classify là một phương thức ActiveSupport cố gắng biến chuỗi thành định dạng lớp chuẩn. Những gì bạn đang làm giống hệt với câu trả lời của Evginey, với một số kiểm tra bổ sung. Trong khi hằng số có lẽ là một giải pháp tốt hơn (vì nó kiểm tra sự lành mạnh), nó giúp hiểu các công cụ bạn sử dụng. – quandrum

+0

Cảm ơn bạn vì điều này, phải trung thực đã không kiểm tra những gì nó làm trong hướng dẫn sử dụng. –

Trả lời

57
klass = Object.const_get "ClassName" 

về các phương pháp lớp

class KlassExample 
    def self.klass_method 
     puts "Hello World from Class method" 
    end 
end 
klass = Object.const_get "KlassExample" 
klass.klass_method 

irb(main):061:0> klass.klass_method 
Hello World from Class method 
+0

Với điều đó bạn không thể truy cập các phương thức lớp học. Giải pháp của tôi ở trên hoạt động chính xác với các phương thức lớp. –

+0

có bạn thực tế có thể –

+0

'Đang tải môi trường phát triển (Rails 3.2.9) irb (chính): 001: 0> name =" PartnerGateway " =>" PartnerGateway " irb (chính): 002: 0> klass = name .constantize.mới => # irb (chính): 003: 0> klass .name => nil' –

24

Những người khác cũng có thể tìm kiếm một sự thay thế mà không ném ra một lỗi nếu nó thất bại trong việc tìm ra lớp. safe_constantize chỉ là vậy.

class MyClass 
end 

"my_class".classify.safe_constantize.new # #<MyClass:0x007fec3a96b8a0> 
"omg_evil".classify.safe_constantize.new # nil 
2

Tôi rất ngạc nhiên khi không ai xem xét bảo mật và hack trong phản hồi của họ. Sự khởi tạo của một chuỗi tùy ý có khả năng đến ngay cả gián tiếp từ đầu vào của người dùng đang yêu cầu sự cố và hack. Tất cả chúng ta nên/phải danh sách trắng trừ khi chúng tôi chắc chắn chuỗi được điều khiển hoàn toàn và theo dõi

def class_for(name) 
    { 
    "foo" => Foo, 
    "bar" => Bar, 
    }[name] || raise UnknownClass 
end 

class_for(name_wherever_this_came_from).create!(params_somehow) 

Làm thế nào bạn sẽ biết params thích hợp tùy tiện mà không cần một danh sách trắng sẽ là một thách thức nhưng bạn sẽ có được ý tưởng.

0

Bạn chỉ có thể chuyển đổi một chuỗi và khởi tạo một lớp ra khỏi nó bằng cách:

klass_name = "Module::ClassName" 
klass_name.constantize 

Để khởi tạo một đối tượng mới:

klass_name.constantize.new 

Tôi hy vọng điều này hóa ra là hữu ích. Cảm ơn!

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