Pregunta Métodos protegidos y privados en Rails


La visibilidad de los métodos en Ruby (métodos públicos, protegidos y privados) ha sido bien explicada en lugares como esta publicación en el blog. Pero en Ruby on Rails parece algo diferente de lo que sería en una aplicación regular de Ruby debido a la forma en que está configurado el framework. Entonces, en los modelos de Rails, controladores, ayudantes, pruebas, etc., ¿cuándo / no es apropiado usar métodos protegidos o privados?

Editar: Gracias por las respuestas hasta ahora. Entiendo el concepto de privacidad y protección en Ruby, pero estoy buscando una explicación de la forma típica en que se usan esos tipos de visibilidad dentro del contexto de varias aplicaciones de Rails (modelos, controladores, ayudantes, pruebas). . Por ejemplo, los métodos de controlador público son métodos de acción, los métodos protegidos en el controlador de la aplicación se usan para "métodos auxiliares" a los que deben acceder múltiples controladores, etc.


76
2017-12-20 23:45


origen


Respuestas:


Para los modelos, la idea es que los métodos públicos sean la interfaz pública de la clase. Los métodos públicos están destinados a ser utilizados por otros objetos, mientras que los métodos protegidos / privados deben ocultarse desde el exterior.

Esta es la misma práctica que en otros lenguajes orientados a objetos.

por controladores y pruebas, solo haz lo que quieras. Ambos controlador y las clases de prueba solo son instanciadas y llamadas por el marco (sí, sé que en teoría puede obtener el controlador desde la vista, pero si lo hace, algo es extraño de todos modos) Como nadie creará esas cosas directamente, no hay nada contra lo que "proteger".

Adición / Corrección: Para los controladores, debe marcar los métodos de "ayuda" como protegido privado, y solo las acciones en sí deberían ser públicas. El marco nunca enrutará ninguna llamada HTTP entrante a acciones / métodos que no sean públicos, por lo que sus métodos auxiliares deberían estar protegidos de esa manera.

Para los ayudantes no importará si un método está protegido o es privado, ya que siempre se llaman "directamente".

Puede marcar cosas protegidas en todos esos casos si le resulta más fácil comprenderlas, por supuesto.


97
2018-01-05 17:47



Usas un método privado si quieres nadie más, pero self para usar un método Usas un método protegido si quieres algo solo self and is_a?(self) s puede llamar.

Un buen uso de protegido podría ser si tuviera un método de inicialización "virtual".

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 tendrá diferentes valores. y las instancias Derivadas no tendrán @baz

Actualizar: Desde que escribí esto, algunas cosas han cambiado en Ruby 2.0+ Aaron Patterson tiene una excelente redacción http://tenderlovemaking.com/2012/09/07/protected-methods-and-ruby-2-0.html


60
2017-12-21 00:08



La diferencia entre protegido y   privado es sutil. Si un método es   protegido, puede ser llamado por cualquier   instancia de la clase definitoria o su   subclases. Si un método es privado,   puede ser llamado solo dentro del contexto   del objeto que llama --- nunca es   posible acceder a otro objeto   los métodos privados de la instancia directamente,   incluso si el objeto es de la misma   clase como la persona que llama. Para protegido   métodos, son accesibles desde   objetos de la misma clase (o   niños).

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


9
2017-12-20 23:54



Parece que tiene una buena idea de la semántica de la visibilidad de clase (pública / protegida / privada) aplicada a los métodos. Todo lo que puedo ofrecer es un resumen rápido de la forma en que lo implemento en mis aplicaciones de Rails.

Implemento métodos protegidos en el controlador de la aplicación base para que puedan ser llamados por cualquier controlador a través de filtros (por ejemplo, before_filter: method_foo). De manera similar, defino métodos protegidos para los modelos que quiero usar en todos ellos en un modelo base del que todos ellos heredan.


3
2018-01-04 07:09



Aunque las acciones deben ser métodos públicos de un controlador, no todos los métodos públicos son necesariamente acciones. Puedes usar hide_action si está utilizando una ruta general como /:controller/:action/:id o si está deshabilitado (el valor predeterminado en Rails 3), solo se invocarán los métodos con rutas explícitas.

Esto puede ser útil si pasa la instancia del controlador a otra biblioteca, como el motor de plantilla de Liquid, ya que puede proporcionar una interfaz pública en lugar de tener que usar enviar los filtros y las etiquetas de Liquid.


2
2018-01-07 11:36