2016-07-25 3 views
0

Ich studiere die Rails-Dokumentation. Im associations documentation geben sie Methodendefinitionen mit einer Kette auf sie, wie folgt aus:Definieren einer verketteten Rubin-Methode Definition ähnlich wie Schienen

Project#portfolio.nil?

Das schien mir seltsam. Es scheint, dass es eine Instanz-Methodendefinition gibt, die eine verkettete Methode enthält. Zum Beispiel: Es scheint, dass Project#portfolio.nil? würde eine Instanz Methode definieren, würde wie folgt aussehen:

class Project < ActiveRecord::Base 

    def portfolio.nil? 
    ... 
    end 
end 

Ich habe wie noch nie zuvor definierten Instanzmethoden gesehen: Wo eine Kette innerhalb der eigentlichen Instanzmethode Definition angegeben ist. Ich habe versucht, es mit reinem Rubin zu replizieren und ich konnte es nicht zur Arbeit bringen.

class Dog 
    def speak 
    puts "woof woof" 
    end 

    def speak.fetch 
    puts "go get the ball!" 
    end 
end 

Dies funktioniert jedoch nicht. Es gibt eine NameError

NameError: undefined local variable or method `speak' for Dog:Class

Wenn es funktioniert hat: dann würde ich Dog.new.speak.fetch versuchen. Ich bin mir nicht sicher, was es zurückgeben würde. Vielleicht wäre es zurück:

=> woof woof! 
=> go get the ball! 

Frage: Ist es sogar möglich, irgendwie Beispiel Methodendefinitionen mit Ketten auf sie wie folgt zu definieren? Wenn nicht: Wie machen Schienen das? Am Beispiel von Project#portfolio.nil?: Wie definiert Rails #portfolio.nil??

Antwort

3

Es ist nur ein Fehler (oder, nennen wir es eine leicht irreführende Formulierung) in der Rails-Dokumentation. Zitat aus http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html:

The project class now has the following methods (and more) to ease the traversal and manipulation of its relationships: Project#portfolio, Project#portfolio=(portfolio), Project#portfolio.nil?

Der dritte Eintrag in dieser Liste ist offensichtlich nur ein Hinweis, dass nil ein gültiger Wert für das Attribut.

(Und die Antwort auf die Frage ist "Nein", Sie können keine Kette von Methoden in Ruby in einem def definieren.)

+0

Ja, das ist die richtige Antwort. –

0

Lassen Sie uns mit einer grundlegenden Sache beginnen:

In Ruby, there are no primitives. Everything is objects. All have one common ancestor, the Object class.

Also, wenn Sie dot notation verwenden Sie Methode von Objekt aufrufen.

Wenn Sie nil? verwenden, bedeutet das, dass Sie eine Methode aufrufen, die überprüft, ob object gleich Null ist. Sie können diese Methode von jedem Objekt aufrufen:

Object.nil? # => false 

In Ihrem Code Sie Project Modell haben die Verbände Portofolio hat.

class Project < ActiveRecord::Base 
    belongs_to :portfolio 
end 

Dokumentation sagt:

Belongs_to: Specifies a one-to-one association with another class.

Methods will be added for retrieval and query for a single associated object, for which this object holds an id: association is a placeholder for the symbol passed as the name argument, so belongs_to :author would add among others author.nil?.

Zum Beispiel:

project = Project.first 
# this will get portfolio from database by foreign key 
puts project.portfolio 
# You can check that there is no records in database 
puts project.portfolio.nil? 

Worten schließen: wenn Sie jede Methode aufrufen, können Sie es von einem Objekt aufrufen.

+1

Was ich denke, meint er, dass Dokumentation 'Projekt # portfolio.nil?' Als eine __separate Methode__ auflistet. Das ist verwirrend. Wie kann das ein Methodenname sein? –

+0

Ja: wie erwähnt: wie kann portfolio.nil? ein Methodenname sein? – Neil