2010-02-23 32 views
8

Có cách nào để tìm tất cả các mô hình đa hình của một loại đa hình cụ thể trong Rails không? Vì vậy, nếu tôi có Group, tổ chức sự kiện, và dự án tất cả với một khai báo như sau:Tìm tất cả bằng Loại đa hình trong Rails?

has_many :assignments, :as => :assignable

Tôi có thể làm điều gì đó như:

Assignable.all

... hoặc

BuiltInRailsPolymorphicHelper.all("assignable")

Điều đó thật tuyệt.

Edit:

... mà Assignable.all lợi nhuận [Event, Group, Product] (mảng của lớp)

+0

Tôi đã thay đổi câu trả lời của tôi dựa trên những thông tin bổ sung mà bạn đã đưa ra. Tôi nghĩ nó sẽ đáp ứng nhu cầu của bạn. –

Trả lời

12

Không có phương pháp trực tiếp cho điều này. Tôi đã viết miếng vá khỉ này cho ActiveRecord::Base. Thao tác này sẽ hoạt động đối với mọi lớp học.

class ActiveRecord::Base 

    def self.all_polymorphic_types(name) 
    @poly_hash ||= {}.tap do |hash| 
     Dir.glob(File.join(Rails.root, "app", "models", "**", "*.rb")).each do |file| 
     klass = (File.basename(file, ".rb").camelize.constantize rescue nil) 
     next if klass.nil? or !klass.ancestors.include?(ActiveRecord::Base) 
     klass.reflect_on_all_associations(:has_many).select{|r| r.options[:as] }.each do |reflection| 
      (hash[reflection.options[:as]] ||= []) << klass 
     end 
     end 
    end 
    @poly_hash[name.to_sym] 
    end 

end 

Bây giờ bạn có thể làm như sau:

Assignable.all_polymorphic_types(:assignable).map(&:to_s) 
# returns ['Project', 'Event', 'Group'] 
+1

BTW, điều này (đáng ngạc nhiên) hoạt động – Dorian

+0

Làm cách nào để thực hiện điều này? thế nào để tôi vào lớp ActiveRecord :: Base để sửa đổi? dường như không thể tìm thấy lớp này trong Dự án của tôi .. – james

+1

@james tham khảo câu trả lời này: http://stackoverflow.com/questions/2328984/rails-extending-activerecordbase/2329394#2329394 –

-1

Bạn sẽ có thể chỉ cần sử dụng bộ sưu tập liên quan:

model.assignments.all 
+0

Điều này sẽ trả về tất cả 'các phép gán' cho một cá thể mô hình. Tôi nghĩ anh ấy muốn trả lại tất cả 'bài tập' cho một loại. –

+0

Nhưng bạn không thể chỉ nói Event.assignments.all? –

+0

Rails không thêm người trợ giúp liên kết tĩnh. Vì vậy, 'Event.assignments' sẽ ném' NoMethodError'. –

0

Tôi tạo ra một lớp mô hình đa hình với một phương pháp 'tất cả' để kiểm tra điều này.

class Profile 
    # Return all profile instances 
    # For class return use 'ret << i' instead of 'ret << i.all' 
    def self.all 
    ret = [] 
    subclasses_of(ActiveRecord::Base).each do |i| 
     unless i.reflect_on_all_associations.select{|j| j.options[:as] == :profile}.empty? 
     ret << i 
     end 
    end 
    ret.flatten 
    end 

    def self.all_associated 
    User.all.map{|u| u.profile }.flatten 
    end 
end 

Đây là thiết lập ứng dụng của tôi:

User < ActiveRecord::Base 
    belongs_to :profile, :polymorphic => true 
end 

Student < ActiveRecord::Base 
    has_one :user, :as => :profile 
end 
+0

Để có được công việc này trong môi trường phát triển, bạn đã yêu cầu các tập tin mô hình. – nanda

+0

Đây là một lớp đặc biệt, không xuống từ ActiveRecord. – nanda

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