2010-02-23 4 views
8

Есть ли способ найти все полиморфные модели определенного полиморфного типа в Rails? Так что, если у меня есть группа, событие, и проект все с заявления, как:Поиск по полиморфному типу в Rails?

has_many :assignments, :as => :assignable

Могу ли я сделать что-то вроде:

Assignable.all

... или

BuiltInRailsPolymorphicHelper.all("assignable")

Это было бы здорово.

Edit:

... такие, что Assignable.all возвращает [Event, Group, Product] (массив классов)

+0

Я изменил свой ответ на основе дополнительной информации, которую вы дали. Я думаю, это поможет вам. –

ответ

12

Там нет прямого метода для этого. Я написал этот патч обезьяны для ActiveRecord::Base. Это будет работать для любого класса.

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 

Теперь вы можете сделать следующее:

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

BTW, это (удивительно) работает – Dorian

+0

Как это реализовать? перейти к классу ActiveRecord :: Base для изменения? возможно, этот класс не найден в моем проекте. – james

+1

@james ссылаются на этот ответ: http://stackoverflow.com/questions/2328984/rails-extending-activerecordbase/2329394#2329394 –

-1

Вы должны быть в состоянии использовать только соответствующую коллекцию:

model.assignments.all 
+0

Это вернет все «присваивания» для экземпляра модели. Я думаю, он хочет вернуть все «присваивания» для типа. –

+0

Но разве вы не можете просто сказать Event.assignments.all? –

+0

Rails не добавляет статические помощники ассоциации. Поэтому 'Event.assignments' будет вызывать' NoMethodError'. –

0

Я создал полиморфный класс модели с помощью метода «все», чтобы проверить это.

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 

Вот мои настройки приложения:

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

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

Чтобы получить эту работу в области разработки, вам потребуются файлы моделей. – nanda

+0

Это специальный класс, не спускающийся с ActiveRecord. – nanda

Смежные вопросы