2011-06-24 62 views
11

Giả sử một Mô hình Rails với các thuộc tính liên tục/không liên tục, thực tiễn tốt nhất về tham chiếu chúng là gì? Nếu bạn xem mã công khai, các mẫu khác nhau sẽ được sử dụng.Sự khác biệt giữa *, self. * Và @ * khi tham chiếu các kết hợp/thuộc tính trong Mô hình/Bộ điều khiển Ruby/Rails

Ví dụ: nếu bạn có liên kết từ mô hình này sang mô hình khác. Sự khác nhau giữa việc sử dụng self.association_name@association_name là gì?. Cách thích hợp hơn là gì?

Tương tự như với các thuộc tính không liên tục được xác định với attr_accessor: attr trong Mô hình. Bạn có thể tham chiếu chúng với cả hai cách tiếp cận, self.attr@attr. Cách thích hợp hơn là gì?

Trả lời

13

self.x/self.x=yluôn là các cuộc gọi phương thức.

(self.x chỉ đường cho self.__send__(:x)self.x = y được thực sự chỉ đường cho self.__send__(:x=, y))

@x, mặt khác, chỉ đề cập đến mộtinstance variable.

Sử dụng @xsẽ không làm việc với các hiệp hội AR như AR chỉ định nghĩa x/x= (đó là phương pháp) cho hoạt động kỳ diệu của nó. (AR về cơ bản chỉ là "chụp" truy cập ý định thông qua những phương pháp và các tuyến đường qua nội bộ cấu trúc dữ liệu riêng của mình mà là không liên quan đến bất kỳ biến dụ tương tự đặt tên.)

attr_accessor phép "truy cập vào cả hai cách" vì và chỉ vì, nó sử dụng biến thể được đặt tên giống như nó sao lưu (nó phải lưu trữ giá trị ở đâu đó). Hãy xem xét rằng attr_accessor :x tương đương với:

def x; @x; end 
def x= (y); @x = y; end 

Mã hóa hạnh phúc.

+0

Về các hiệp hội:. Tôi thực sự phải sử dụng tự * để tham khảo họ? Nhược điểm của việc bỏ qua tự. * Trong bối cảnh này là gì? – Scholle

+2

@Scholle Bạn phải sử dụng 'self.x = y' nếu không Ruby sẽ nghĩ bạn muốn gán đánh giá' y' vào biến địa phương 'x' (mà nó sẽ làm vui vẻ, tạo nó nếu cần). Tuy nhiên, giả sử không có biến 'x' trong phạm vi, sau đó' self.x' và 'x' cả hai sẽ gọi phương thức' x'. Một số người thích bỏ qua 'self' trong trường hợp này (tôi sẽ). Vấn đề lớn là * phải nhất quán *. –

6

Hầu hết thời gian, bạn muốn sử dụng attr thay vì @attr. Đó là bởi vì phương pháp attr thường đặt thuộc tính nếu nó không tồn tại.

Ví dụ mô hình này theo thứ tự:

model Order 
    have_many :items 

    def total 
    @total ||= items.collect(&:price).sum 
    end 

    def taxes 
    @taxes ||= total * 0.10 
    end 
end 

mô hình này hoạt động Vell, nếu tôi đã sử dụng @total thay vì total trong phương pháp taxes, các calcul sẽ thất bại nếu tôi không gọi phương thức total về đối tượng này trước.

Khi @pst chỉ ra, @association_name không hoạt động để liên kết, bạn PHẢI sử dụng phương thức association_name.

Cũng self.attr nên chỉ được sử dụng để thiết lập một thuộc tính (gọi self.attr=) khi đọc giá trị mà bạn đang tốt hơn để sử dụng attr, xem this article : When to used self Rails model

+0

+1 Để làm tròn câu trả lời của tôi: p –

+0

Trong bài viết bạn đăng nó nói "không bao giờ sử dụng biến cục bộ có cùng tên với thuộc tính". Điều này về cơ bản có nghĩa là bạn phải kiểm tra mã của bạn mỗi lần sau khi bạn đã giới thiệu một thuộc tính mới cho dù bạn có một biến địa phương có cùng tên không? Ví dụ, bạn có hai phương thức def start_time ... end (getter) và def start_time ... end (setter). Theo bài báo, viết mã xấu là sử dụng biến cục bộ được gọi là start_time (ví dụ: để tính thời gian)? – Scholle

+0

Cảm giác chính xác của câu này là nếu bạn có thuộc tính, ví dụ '@ total', bạn không nên sử dụng biến có tên' total' trong phương thức của lớp này, bởi vì khi bạn đang sử dụng 'total' làm biến nó gây nhầm lẫn giữa việc sử dụng biến 'total' và gọi người truy cập của' @ total' (nếu có). Vì vậy, bạn là đúng, bạn không nên sử dụng một biến gọi là 'start_time' nếu bạn có một phương thức' start_time' trong lớp của bạn nhưng bạn có thể muốn sử dụng các thuộc tính '@ start_time' để lưu trữ giá trị ** nếu cần ** –

Các vấn đề liên quan