ruby-on-rails - Anular los métodos de atributo de ActiveRecord




oop (5)

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"

las otras dos respuestas son buenas y parecen funcionar.

Sin embargo, si su complemento consiste en un único archivo .rb en proveedor / plugins / ... / lib y el proveedor / plugins / ... / init.rb es solo un

require 'pluginname'

Luego puede simplemente copiar el archivo individual en su directorio lib y agregar un archivo a config / initializers que requiera 'yourpluginname'

Aquí hay un ejemplo concreto que utiliza el plugin acts_as_rated, que todavía no es una joya.

  1. copie el proveedor / plugins / acts_as_rated / lib / acts_as_rated.rb a lib /
  2. crea un archivo config / initializers / acts_as_rated.rb con lo siguiente ...

    requiere 'acts_as_rated'

  3. eliminar proveedor / plugins / acts_as_rated





ruby-on-rails oop activerecord