Câu hỏi Phương pháp được bảo vệ và riêng tư trong Rails


Phương thức hiển thị trong Ruby (các phương thức công khai, được bảo vệ và riêng tư) đã được giải thích rõ ở những nơi như bài đăng trên blog này. Nhưng trong Ruby on Rails, nó có vẻ hơi khác so với trong ứng dụng Ruby thông thường vì cách khung được thiết lập. Vì vậy, trong các mô hình Rails, bộ điều khiển, trợ giúp, kiểm tra, v.v., khi nào / không thích hợp để sử dụng các phương thức được bảo vệ hay riêng tư?

Chỉnh sửa: Cảm ơn cho câu trả lời từ trước đến nay. Tôi hiểu khái niệm về bảo mật và riêng tư trong Ruby, nhưng tôi đang tìm cách giải thích cách điển hình hơn là các kiểu hiển thị được sử dụng trong bối cảnh các phần khác nhau của ứng dụng Rails (mô hình, bộ điều khiển, người trợ giúp, kiểm thử) . Ví dụ, phương pháp điều khiển công cộng là phương pháp hành động, phương pháp bảo vệ trong bộ điều khiển ứng dụng được sử dụng cho "phương pháp trợ giúp" cần phải được truy cập bởi nhiều bộ điều khiển, vv


76
2017-12-20 23:45


gốc




Các câu trả lời:


Đối với các mô hình, ý tưởng là các phương thức công khai là giao diện công khai của lớp. Các phương thức công khai được dự định sẽ được sử dụng bởi các đối tượng khác, trong khi các phương thức được bảo vệ / riêng sẽ được ẩn từ bên ngoài.

Đây là thực hành tương tự như trong các ngôn ngữ hướng đối tượng khác.

Dành cho bộ điều khiển và kiểm tra, chỉ cần làm như bạn vui lòng. Cả bộ điều khiển và các lớp kiểm thử chỉ được khởi tạo và được gọi bởi khung công tác (có, tôi biết bạn về mặt lý thuyết có thể có được bộ điều khiển từ xem, nhưng nếu bạn làm điều đó, một cái gì đó là lạ anyway). Vì không ai có thể tạo ra những thứ đó trực tiếp, nên không có gì để "bảo vệ" chống lại.

Phụ lục / Sửa đổi: Đối với bộ điều khiển, bạn nên đánh dấu các phương thức "trợ giúp" là được bảo vệ riêng tư và chỉ các hành động của họ phải được công khai. Khung công tác sẽ không bao giờ định tuyến bất kỳ cuộc gọi HTTP đến nào đến các hành động / phương thức không công khai, vì vậy các phương thức trợ giúp của bạn phải được bảo vệ theo cách đó.

Đối với những người trợ giúp, nó sẽ không tạo ra sự khác biệt nếu một phương thức được bảo vệ hoặc riêng tư, vì chúng luôn được gọi là "trực tiếp".

Bạn có thể đánh dấu các công cụ được bảo vệ trong tất cả các trường hợp đó nếu nó giúp mọi thứ dễ hiểu hơn, tất nhiên.


97
2018-01-05 17:47



"Đối với bộ điều khiển, bạn nên đánh dấu các phương thức "trợ giúp" như được bảo vệ và chỉ các hành động của chúng phải được công khai."Bạn đang khuyên không nên có bất kỳ phương pháp riêng trong bộ điều khiển? Hay tôi không nên đọc nó theo nghĩa đen? - Dennis
Ngày nay tôi chỉ sử dụng riêng tư. được bảo vệ và riêng tư được sử dụng thay thế cho nhau ở hầu hết các nơi; nhưng được bảo vệ mang lại một hành vi kỳ lạ mà tôi không bao giờ cần trong thế giới thực. - averell
Tôi cũng chỉ sử dụng riêng tư. Điều này cũng tuân theo các nguyên tắc nhất định, chẳng hạn như Thoughtbot's "Sử dụng riêng tư thay vì được bảo vệ khi xác định phương pháp điều khiển." - Dennis


Bạn sử dụng phương thức riêng tư nếu bạn muốn không ai khác ngoài self để sử dụng một phương pháp. Bạn sử dụng một phương pháp được bảo vệ nếu bạn chỉ muốn một cái gì đó self and is_a?(self) s có thể gọi.

Một cách sử dụng tốt được bảo vệ có thể là nếu bạn có phương thức khởi tạo "ảo".

class Base
    def initialize()
        set_defaults()
        #other stuff
    end

    protected
    def set_defaults()
        # defaults for this type
        @foo = 7
        calculate_and_set_baz()
    end

    private
    def calculate_and_set_baz()
        @baz = "Something that only base classes have like a file handle or resource"
    end
end

class Derived < Base
    protected
    def set_defaults()
        @foo = 13
    end
end

@foo sẽ có các giá trị khác nhau. và các cá thể có nguồn gốc sẽ không có @baz

Cập nhật: Vì tôi đã viết điều này, một số thứ đã thay đổi trong Ruby 2.0+ Aaron Patterson có một bài viết tuyệt vời http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html


60
2017-12-21 00:08



Yêu cách bạn nói self and is_a?(self). Tôi đã luôn luôn giải thích phương pháp bảo vệ như là có sẵn trong các lớp học trẻ em. - Tate Johnson
Chú ý ở đây! Đây là sự khác biệt quan trọng đối với các ngôn ngữ khác: Phương pháp riêng tư là cũng thế có sẵn trong các lớp học trẻ em. Sự khác biệt duy nhất trong bảo mật và riêng tư là bạn có thể gọi các phương thức được bảo vệ bằng "self.set_defaults", trong khi các phương thức riêng chỉ có thể được gọi là "set_defaults". - averell
Một câu trả lời tốt, nhưng thậm chí không chứa từ Rails là điểm của câu hỏi - Bryan Ash
Chú ý đến dấu hiệu Chỉnh sửa thời gian của câu hỏi của anh ta. Trong tương lai, tôi sẽ xác định một phương pháp riêng để cập nhật câu trả lời của tôi khi họ thay đổi câu hỏi của họ :) - EnabrenTane
Như averell đã nói, lời giải thích này không áp dụng cho ruby. Trường hợp các phương thức riêng cũng có thể nhìn thấy trong các lớp con. - Miguel


Sự khác biệt giữa bảo vệ và   riêng tư là tinh tế. Nếu phương thức là   được bảo vệ, nó có thể được gọi bởi bất kỳ   thể hiện của lớp xác định hoặc   các lớp con. Nếu phương thức là riêng tư,   có thể được gọi chỉ trong ngữ cảnh   của đối tượng gọi --- nó không bao giờ   có thể truy cập một đối tượng khác   các phương thức riêng tư của cá thể trực tiếp,   ngay cả khi đối tượng giống nhau   lớp như người gọi. Để bảo vệ   phương pháp, họ có thể truy cập từ   đối tượng của cùng một lớp (hoặc   bọn trẻ).

http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Classes#Declaring_Visibility


9
2017-12-20 23:54



Cảm ơn các liên kết. Nhưng tôi tự hỏi nhiều hơn về cách các công việc này đặc biệt trong Ruby on Rails (các phương thức điều khiển công cộng được coi là các phương thức hành động, các phương thức được bảo vệ trong bộ điều khiển ứng dụng có thể được sử dụng bởi các bộ điều khiển khác, v.v.) - jrdioko
Trong trường hợp cuối cùng "các phương thức được bảo vệ trong bộ điều khiển ứng dụng có thể được sử dụng bởi các bộ điều khiển khác", điều này là do các bộ điều khiển khác (nói chung) Kế thừa từ ApplicationController để họ thực sự sở hữu tất cả các phương thức đó. Họ không truy cập chúng từ application_controller: điều này không bao giờ được khởi tạo. Nó hoàn toàn được sử dụng như một phụ huynh để kế thừa từ. - Max Williams


Bạn dường như có một ý tưởng tốt về ngữ nghĩa của khả năng hiển thị lớp (public / protected / private) như được áp dụng cho các phương thức. Tất cả tôi có thể cung cấp là một phác thảo nhanh chóng về cách tôi thực hiện nó trong các ứng dụng Rails của tôi.

Tôi thực hiện các phương thức được bảo vệ trong bộ điều khiển ứng dụng cơ sở để chúng có thể được gọi bởi bất kỳ bộ điều khiển nào thông qua các bộ lọc (ví dụ: before_filter: method_foo). Theo cách tương tự, tôi định nghĩa các phương thức được bảo vệ cho các mô hình mà tôi muốn sử dụng trong tất cả chúng trong một mô hình cơ sở mà tất cả chúng đều được kế thừa từ đó.


3
2018-01-04 07:09





Mặc dù các hành động cần phải là các phương thức công khai của một bộ điều khiển, nhưng không phải tất cả các phương thức công cộng đều nhất thiết là các hành động. Bạn có thể dùng hide_action nếu bạn đang sử dụng tuyến đường bắt sóng như /:controller/:action/:id hoặc nếu nó bị vô hiệu hóa (mặc định trong Rails 3) thì chỉ có các phương thức có các tuyến đường rõ ràng mới được gọi.

Điều này có thể hữu ích nếu bạn đang truyền thể hiện điều khiển cho một số thư viện khác như công cụ mẫu Liquid vì bạn có thể cung cấp giao diện công khai thay vì phải sử dụng gửi trong bộ lọc và thẻ Chất lỏng của bạn.


2
2018-01-07 11:36