ruby-on-rails - queries - ruby rails guide




Anular los métodos de atributo de ActiveRecord (3)

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

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?


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

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"




activerecord