Pregunta ¿Hay alguna forma de hacer que Rails ActiveRecord sea privado?


De forma predeterminada, ActiveRecord toma todos los campos de la tabla de base de datos correspondiente y crea atributos públicos para todos ellos.

Creo que es razonable no para hacer públicos todos los atributos en un modelo. Aún más, la exposición de atributos que están destinados al uso interno desordena la interfaz del modelo y viola el principio de encapsulación.

Entonces, ¿hay alguna manera de hacer algunos de los atributos literalmente private?

¿O tal vez debería pasar a algún otro ORM?


32
2017-09-21 22:13


origen


Respuestas:


Jordini estuvo la mayor parte del camino

La mayoría de active_record ocurre en method_missing. Si define el método por adelantado, no golpeará method_missing para ese método, y usará el suyo en lugar (sobrescribiendo efectivamente, pero no realmente)

class YourModel < ActiveRecord::Base

  private

  def my_private_attribute
    self[:my_private_attribute]
  end

  def my_private_attribute=(val)
    write_attribute :my_private_attribute, val
  end

end

29
2017-09-22 00:44



Tropezado con esto recientemente. Si quieres escribir y leer en privado y leer en público algo como esto

class YourModel < ActiveRecord::Base

  attr_reader :attribute

  private

  attr_accessor :attribute


end

Parece funcionar bien para mi. Puede jugar con attr_reader, attr_writer y attr_accessor para decidir qué debe exponerse y qué debe ser privado.


6
2017-08-17 00:22



bueno, siempre puedes anular los métodos ...

class YourModel < ActiveRecord::Base

  private

  def my_private_attribute
    self[:my_private_attribute]
  end

  def my_private_attribute=(val)
    self[:my_private_attribute] = val
  end

end

5
2017-09-21 23:52



Puede hacer que un método existente sea privado:

YourClass.send(:private, :your_method)

1
2017-09-22 00:36



Para mí, los métodos de Otto y jordinl funcionan bien y hacen que rspec para el objeto de clase pase:

object.should_not respond_to :attribute

Pero cuando uso el método jordinl, tengo un mensaje de desaprobación para no escribir directamente en la base de datos, pero en su lugar uso attr_writer.

ACTUALIZAR:

Pero el verdadero método "correcto" para hacerlo resulta ser simple. Gracias a Mladen Jablanović y Christopher Creutzig de aquí. Para hacer que el método predefinido sea privado o protegido ... simplemente redefinirlo:

Class Class_name

  private :method_name
  protected :method_name_1
end

Lo que es importante, no necesita reescribir la lógica del método previamente definido.


1
2018-01-14 21:59



Hacer que la configuración sea privada genera un error de ActiveRecord.

Pongo el código de control de acceso en el método sobrescrito del organismo público al marcar a la persona que llama:

def my_private_attribute=(val)
  if (caller.first.include?('active_record/base.rb') || caller.first.include?('app/models/myclass.rb'))
    self[:my_private_attribute] = val
  else
     raise Exception.new("Cannot set read-only attribute.")
  end
end

0
2017-11-26 01:01



No creo que haya una manera 100% confiable de hacer esto. También vale la pena verificar las formas más populares de acceder a los atributos:

http://www.davidverhasselt.com/set-attributes-in-activerecord/


0
2017-11-11 18:34