2011-06-24 19 views
11

Suponiendo un modelo de Rails con atributos persistentes/no persistentes, ¿cuál es la mejor práctica para hacer referencia a ellos? Si observa el código públicamente disponible, se usan diferentes patrones.Diferencias entre *, self. * Y @ * al hacer referencia a asociaciones/atributos en Ruby/Rails Models/Controllers

Por ejemplo, si tiene una asociación de un modelo a otro. ¿Cuál es la diferencia entre usar self.association_name y @association_name?. ¿Cuál es la forma preferible?

Igual que con atributos no persistentes definidos con attr_accessor: attr en Modelos. Puede hacer referencia a ellos con ambos enfoques, self.attr y @attr. ¿Cuál es la forma preferible?

Respuesta

13

self.x/self.x=yson siempre llamadas a métodos.

(self.x es sólo azúcar para self.__send__(:x) y self.x = y es en realidad azúcar para self.__send__(:x=, y))

@x, por el contrario, sólo se refiere a un instance variable.

Usando @xno funcionará con las asociaciones de AR como AR sólo define x/x= (que son métodos) para su funcionamiento mágico. (AR esencialmente sólo "captura" acceso intención a través de estos métodos y rutas a través de sus propias estructuras de datos internos que son no relacionado a cualquier variables de instancia-similares nombrado.)

attr_accessor permite "acceder a ambas formas" porque y solo porque usa la variable de instancia con el mismo nombre que el respaldo (tiene que almacenar el valor en alguna parte). Tenga en cuenta que attr_accessor :x es equivalente a:

def x; @x; end 
def x= (y); @x = y; end 

Happy coding.

+0

En cuanto a las asociaciones:. ¿Tengo realmente que usar auto * para hacer referencia a ellos? ¿Cuál es la desventaja de saltearse a sí mismo. * En este contexto? – Scholle

+2

@Scholle Debe usar 'self.x = y'; de lo contrario, Ruby pensaría que desea asignar la evaluación de' y' a la variable local 'x' (lo cual hará felizmente, creándola si es necesario). Sin embargo, suponiendo que no hay una variable 'x' en el alcance, entonces' self.x' y 'x' invocarán el método' x'. Algunas personas prefieren omitir 'self' en este caso (lo haría). El gran problema es * ser consistente *. –

6

La mayoría de las veces, preferiría usar attr en lugar de @attr. Es porque el método attr a menudo establece los atributos si no existe.

Por ejemplo, este modelo de orden:

model Order 
    have_many :items 

    def total 
    @total ||= items.collect(&:price).sum 
    end 

    def taxes 
    @taxes ||= total * 0.10 
    end 
end 

Este modelo funciona vell, si hubiera utilizado @total en lugar de total en el método taxes, la Calcul fallado si no llamar método total en este objeto antes de.

Como @pst señala, @association_name no funciona para la asociación, TIENE QUE usar el método association_name.

también self.attr sólo debe utilizarse para establecer un atributo (llamando self.attr=) cuando se lee el valor que es mejor utilizar attr, ver this article : When to used self Rails model

+0

+1 Para redondear mi respuesta: p –

+0

En el artículo que publicó dice "nunca use variables locales que tengan el mismo nombre que los atributos". Esto básicamente significa que debe verificar su código cada vez que haya introducido un nuevo atributo, ya sea que tenga una variable local con el mismo nombre. Por ejemplo, tiene dos métodos def start_time ... end (getter) y def start_time ... end (setter). Según el artículo, es una mala codificación usar una variable local llamada start_time (por ejemplo, para calcular un tiempo)? – Scholle

+0

El sentido exacto de esta oración es que si tiene un atributo, por ejemplo '@ total', no debe usar una variable llamada' total' en un método de esta clase, esto es porque cuando está usando 'total' como variable es confuso entre usar la variable 'total' y llamar al descriptor de acceso de' @ total' (si existe). Así que tienes razón, no debes usar una variable llamada 'start_time' si tienes un método' start_time' en tu clase, pero es posible que quieras utilizar los atributos '@ start_time' para almacenar el valor ** si es necesario ** –