ruby on rails - queries - Anular los métodos de atributo de ActiveRecord
ruby on rails queries (4)
Un ejemplo de lo que estoy hablando:
class Person < ActiveRecord::Base
def name=(name)
super(name.capitalize)
end
def name
super().downcase # not sure why you''d do this; this is just an example
end
end
Esto parece funcionar, pero acabo de leer la sección sobre métodos de atributo de anulación en los documentos ActiveRecord :: Base , y sugiere utilizar los métodos read_attribute
y write_attribute
. Pensé que debe haber algo mal con lo que estoy haciendo en el ejemplo anterior; de lo contrario, ¿por qué bendecirían estos métodos como la "forma correcta" de anular los métodos de los atributos? También están forzando un modismo mucho más feo, por lo que debe haber una buena razón ...
Mi verdadera pregunta: ¿Hay algo mal con este ejemplo?
Como una extensión de la respuesta de Aaron Longwell, también puede usar una "notación hash" para acceder a los atributos que tienen accesadores y mutadores anulados:
def name=(name)
self[:name] = name.capitalize
end
def name
self[:name].downcase
end
Haciéndose eco de los comentarios de Gareth ... tu código no funcionará como está escrito. Debe ser reescrito de esta manera:
def name=(name)
write_attribute(:name, name.capitalize)
end
def name
read_attribute(:name).downcase # No test for nil?
end
Hay buena información disponible sobre este tema en http://errtheblog.com/posts/18-accessor-missing .
En resumidas cuentas, ActiveRecord maneja correctamente las llamadas súper para los accesos de atributos de ActiveRecord.
Tengo un complemento de rieles que hace que la anulación de atributos funcione con super como es de esperar. Puedes encontrarlo en github .
Instalar:
./script/plugin install git://github.com/chriseppstein/has_overrides.git
Usar:
class Post < ActiveRecord::Base
has_overrides
module Overrides
# put your getter and setter overrides in this module.
def title=(t)
super(t.titleize)
end
end
end
Una vez que has hecho eso, las cosas funcionan:
$ ./script/console
Loading development environment (Rails 2.3.2)
>> post = Post.new(:title => "a simple title")
=> #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil>
>> post.title = "another simple title"
=> "another simple title"
>> post.title
=> "Another Simple Title"
>> post.update_attributes(:title => "updated title")
=> true
>> post.title
=> "Updated Title"
>> post.update_attribute(:title, "singly updated title")
=> true
>> post.title
=> "Singly Updated Title"