Различия между *, self.* И @* при ссылке на ассоциации / атрибуты в Ruby/Rails Models/Controllers
Предполагая, что модель Rails с постоянными / непостоянными атрибутами, какова лучшая практика при обращении к ним? Если вы посмотрите на общедоступный код, используются разные шаблоны.
Например, если у вас есть связь от одной модели к другой. В чем разница между использованием self.association_name и @association_name?, Какой способ предпочтительнее?
То же, что и с непостоянными атрибутами, определенными с помощью attr_accessor: attr в моделях. Вы можете ссылаться на них с обоими подходами, self.attr и @attr. Какой способ предпочтительнее?
2 ответа
self.x
/ self.x=y
всегда вызовы метода.
(self.x
это просто сахар для self.__send__(:x)
а такжеself.x = y
на самом деле просто сахар дляself.__send__(:x=, y)
)
@x
с другой стороны, относится только к переменной экземпляра.
С помощью@x
не будет работать с ассоциациями AR, так как AR только определяетx/x=
(которые являются методами) для его магической операции. (По сути, AR просто "захватывает" намеренный доступ через эти методы и маршруты через свои собственные внутренние структуры данных, которые несвязаны ни с какими именными переменными экземпляра.)
attr_accessor
позволяет "получить доступ к обоим путям", потому что и только потому, что он использует переменную экземпляра с тем же именем в качестве своей основы (он должен где-то хранить значение). Считают, что attr_accessor :x
эквивалентно:
def x; @x; end
def x= (y); @x = y; end
Удачного кодирования.
Большую часть времени вы бы предпочли использовать attr
вместо @attr
, Это потому, что метод attr
часто устанавливать атрибуты, если он не существует.
Например этот модельный заказ:
model Order
have_many :items
def total
@total ||= items.collect(&:price).sum
end
def taxes
@taxes ||= total * 0.10
end
end
Эта модель работает хорошо, если бы я использовал @total
вместо total
в методе taxes
, исчисление будет неудачным, если я не вызову метод total
на этом объекте раньше.
Как указывает @pst, @association_name
не работает для ассоциации, вы должны использовать метод association_name
,
Также self.attr
следует использовать только для установки атрибута (вызов self.attr=
) при чтении значения лучше использовать attr
, см. эту статью: Когда использовать собственную модель Rails