ruby on rails - ¿Hay alguna forma de hacer que Rails ActiveRecord sea privado?
ruby-on-rails private (7)
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
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 hacer públicos todos los atributos de 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 que algunos de los atributos sean literalmente private
?
¿O tal vez debería pasar a algún otro ORM?
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
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/
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 desde 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.
Puede hacer que un método existente sea privado:
YourClass.send(:private, :your_method)
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.
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