2009-06-22 57 views
2

裏面我有一個Rails模型類導軌的has_many和訪問

class Model < ActiveRecord::Base 

    has_many :object_collection 


    def add_object(object) 
     object_collection.push object // works 
     @object_collection.push object // does not work 
     self.object_collection.push object // works 
    end 
end 

我想知道如果有人能請向我解釋爲什麼@尚不能工作自做我認爲這兩個意思相同

歡呼聲

+0

所有的好回答歡呼傢伙, – ssmithstone 2009-06-22 21:44:29

回答

4

它們是不一樣的。請看下面的Ruby代碼:

class Person 
    attr_accessor :employer 
end 
john = Person.new 
john.employer = "ACME" 
john.employer # equals "ACME" 

的方法attr_accessor方便地爲你生成一個屬性讀寫器(employer=employer)。您可以使用這些方法來讀取和寫入存儲在實例變量@employer中的屬性。現在

,我們可以在上述改寫爲以下,這在功能上等同於上面的代碼:現在

class Person 
    def employer=(new_employer) 
    @works_for = new_employer 
    end 
    def employer 
    @works_for 
    end 
end 
john = Person.new 
john.employer = "ACME" 
john.employer # equals "ACME" 

,實例變量@employer不再使用。我們選擇手動編寫訪問器,並且可以自由地爲實例變量選擇不同的名稱。在此特定示例中,實例變量的名稱與屬性訪問器的名稱不同。沒有什麼能阻止你這樣做。

這與ActiveRecord如何在內部存儲其屬性類似。它們不存儲在相同名稱的實例變量中,這就是爲什麼您的push調用@object_collection不起作用。

如您所知,屬性讀者和作者提供了一定的抽象,可以隱藏您的實現細節。因此直接在子類中讀寫實例變量通常被認爲是不好的做法。

1

@foo標識一個名爲@foo的實例變量。 foo找到了一個名爲foo的方法。 默認情況下,Ruby中的實例變量是私有的。這意味着你不能訪問實例變量的值,除非你有一些公開的方法公開這個值。

這些方法被稱爲setter和getters。通過傳統,setter和getter具有相同的實例變量名稱,但這不是必需的。

class MyClass 

    def initialize 
    @foo 
    end 

    def foo=(value) 
    @foo = foo 
    end 
    def foo 
    @foo 
    end 

    def an_other_foo=(value) 
    @foo = foo 
    end 
    def an_other_foo 
    @foo 
    end 

end 

雖然方法和實例變量可以具有相似的名稱,thery是不同的元素。 如果你不清楚這個話題,你可能需要停止使用Rails,並回頭研究Ruby的工作方式。

在您的具體情況下,object_collection不存在作爲實例變量,因爲它是一種關聯方法。

1

他們不是這個意思。一個是實例變量,另一個是方法。

@foo表示「實例變量foo的值」,其中self.foo的意思是「對我自己的foo方法的調用的值」。

foo =方法設置@foo實例變量是很典型的,所以我可以看到新來的人可能會被混淆。我鼓勵你拿起一本關於Ruby語言的書。有一個專門針對那些已經完成了一些軌道但從未學過紅寶石的人。你經常可以在不理解語言或者這些語句意味着什麼的情況下進行攻擊,但是與那些花很少時間學習Ruby語言本身的人相比,你的效率要低得多。

作爲一般規則,請儘可能使用self.foo格式,因爲它對類定義中的更改不太敏感。