2011-02-15 111 views
1

基本底漆:has_many關係的實際類是什麼?

class User 
    has_many :programs, :through => :memberships 
    has_many :memberships 
end 

class Program 
end 

class Membership 
    belongs_to :user 
    belongs_to :program 
end 

控制檯:

User.new.save 
Program.new.save 
User.programs << Program.first 

User.first.programs.class 
# => Array 
User.first.programs.methods.grep /where/ 
# => [] 
User.first.programs.where :id => 1 
# => [#<Program id: 1>] 
User.first.programs.where(:id => 1).class 
# => ActiveRecord::Relation 

所以現在的問題是,User.first.programs的的has_many方法,似乎返回叫聲像ActiveRecord::Relation並接受像Relation方法的結果,但自識別爲Array,並與類Array的實例共享其方法。

那麼是什麼給?

回答

4

這的確令人吃驚,不知道這是否是最好的解決辦法,但至少它的記錄(在AssociationProxy類):

在blog.posts 協會代理在博客對象作爲@owner,其帖子的 集合作爲@target, 和@reflection對象代表 a:has_many宏。

該類已將絕大多數基本的 實例方法刪除,並且 通過method_missing將未知方法委託給@target 。作爲一個角落的情況下, 甚至消除類方法和 這就是爲什麼你

blog.posts.class#=>陣列雖然 blog.posts後面的對象不是一個數組 ,而是 ActiveRecord的: :協會:: HasManyAssociation。

+0

事實上,Rails中的一個更加棘手的部分(和Ruby相關)。當然,後續問題是:除了祈禱文檔之外,如何處理這種情況?這裏有一個這樣的問題:http://stackoverflow.com/questions/5446331/metaprogramming-how-to-discover-the-real-class-of-an-object – Chinasaur

+0

Ruby的黑暗魔法來設計,這沒關係,所以我會說避免這種問題的最好方法就是「不要這樣做」。我沒有檢查,但我認爲(我希望)它在Rails 3中的表現完全不同。 – tokland

+0

我同意,只要你知道存在黑暗魔法就沒關係。但是當它發生並且沒有很好的文檔記錄時,它是可怕的,所以如果有一個可靠的方法來檢測和處理這些情況將會很不錯。我只是覺得必須有一種方法來獲得REAL課程。 – Chinasaur