2009-08-28 15 views
51

Tôi vừa bắt đầu học Ruby on Rails và tôi đã gặp phải mã như dưới đây:cuộc gọi của Ruby Phương pháp khai báo trong lớp cơ

class Post < ActiveRecord::Base 
validates_presence_of :title 
belongs_to :user 
end 

Có hai phương pháp gọi bên trong cơ thể lớp. Tôi đã gặp khó khăn trong việc tìm kiếm bất kỳ tài liệu về ruby ​​nào mà mô tả cách thức các cuộc gọi phương thức từ bên trong cơ thể của một lớp (nhưng bên ngoài phương thức bất kỳ) hoạt động. Tất cả các sách tôi có, chỉ mô tả cách xác định các phương thức lớp và thể hiện và cách gọi chúng từ bên trong các phương thức khác.

Các câu hỏi tôi có là: Làm cách nào và khi nào các phương pháp này được gọi? Chúng được xác định như thế nào? Chúng có phải là mixin được định nghĩa trong một số mô-đun ghi hoạt động không?

Trả lời

3

Những gì bạn thấy là các phương thức cấp lớp cho đối tượng ActiveRecord. Để viết các phương thức của riêng bạn thực hiện như thế bạn sẽ viết chúng như một plugin và sau đó đưa chúng vào ActiveRecord bằng cách mở lại định nghĩa lớp. Ruby on Rails hướng dẫn để tạo ra một plugin:

http://guides.rubyonrails.org/plugins.html

Covers thế nào người ta sẽ viết như một phương pháp plugin/lớp cấp. Đó là một tài liệu tốt về cách quấn đầu của bạn xung quanh những loại phương pháp đó có ý nghĩa gì và cách chúng tương tác với các cá thể.

+1

Đá quý cũng hoạt động. –

11

Re: Làm thế nào và khi nào các phương pháp này được gọi là?

[Chúng được gọi khi lớp được tải. Bạn có thể đặt điểm ngắt trong một trong các phương pháp và thấy rằng nó được gọi là một phần của khởi động dự án đường ray của bạn.]

Chúng được xác định như thế nào?

[Phương pháp lớp học. Vì đây là ruby, chúng có thể được xác định theo một số cách.]

Chúng là các mixin được định nghĩa trong một số mô-đun ghi đang hoạt động?

[Trong trường hợp này,

validates_presence_of được định nghĩa trong vendor/ray/activerecord/lib/active_record/validations.rb

belongs_to được định nghĩa trong vendor/ray/activerecord/lib/active_record/associations.rb

ActiveRecord là một hệ thống lớn, bao gồm nhiều mixins, mô-đun, vv

Lưu ý, để xem nơi các phương pháp được định nghĩa, tôi sử dụng http://www.gotapi.com/rubyrails cho mỗi phương thức, xem liên kết "Hiển thị nguồn" ở cuối định nghĩa.

]

29

Phần thân của định nghĩa lớp là ngữ cảnh thực thi cho mã giống như bất kỳ cách nào khác. Mã được thực hiện trong ngữ cảnh của lớp (có nghĩa là self là đối tượng lớp, là một thể hiện của lớp). Bạn có thể có các biến cục bộ và cá thể (mà sẽ thuộc về đối tượng lớp chính nó chứ không phải là các cá thể của lớp) và bạn có thể gọi bất kỳ phương thức nào mà đối tượng lớp trả lời. Mã được chạy sau khi khối định nghĩa lớp được hoàn thành.

Trong trường hợp này, ActiveRecord :: Base xác định các phương thức lớp validates_presence_ofbelongs_to.

11

Đây là các phương pháp lớp hoặc phương pháp 'singleton'. Một trong những bạn nên quen thuộc với attr_accessor. Chúng tôi có thể thực hiện một cái gì đó giống như nó trong một lớp học thử nghiệm.

class Klass 
    def self.add_getter_and_setter(symbol) 
    module_eval "def #{symbol}; @#{symbol}; end" 
    module_eval "def #{symbol}=(val); @#{symbol} = val; end" 
    end 
end 

class Person < Klass 
    add_getter_and_setter :name 
    add_getter_and_setter :phone 
end 

person = Person.new 
person.name = 'John Smith' 
person.phone = '555-2344' 
person # returns <Person:0x28744 @name="John Smith", @phone="555-2344"> 

Trong ví dụ trên, chúng tôi đã tạo phương thức lớp bằng 'def self.add_getter_and_setter' nhưng đây không phải là cách duy nhất.

class Klass 
    class << self # opens the singleton class 
    def add_getter_and_setter(symbol) # note we dont specify self as it is already within the context of the singleton class 
     .. 
    end 
    end 
end 

Sử dụng mở rộng. Mở rộng mô-đun # là một phương thức mở rộng một lớp với các phương thức lớp tương tự như vậy phương thức Module # include bao gồm một lớp với các phương thức ví dụ.

class Klass 
    extend(Module.new do 
    def add_getter_and_setter(symbol) 
     .. 
    end 
    end) 
end 

Nếu Klass đã được xác định chúng ta có thể mở lại nó để thêm các phương pháp lớp

class Klass 
end 

def Klass.add_getter_and_setter(symbol) 
    .. 
end 

# or 

class << Klass 
    def add_getter_and_setter(symbol) 
    .. 
    end 
end 

Vâng những là một vài cách để tôi biết làm thế nào để làm điều này vì vậy nếu bạn thấy cú pháp khác nhau chỉ nhận ra tất cả của nó làm điều tương tự.

Lưu ý: trong đường ray, một phương pháp phổ biến mà tất cả chúng ta sử dụng là 'tìm'. Nó được chạy trực tiếp ra khỏi lớp Model.

person = Person.find(1) # finds a person with id:1 
Các vấn đề liên quan