Как перезаписать метод getter в модели ActiveRecord?
Я пытаюсь перезаписать метод геттера для модели ActiveRecord. У меня есть атрибут под названием name
модель Category
, и я хотел бы иметь возможность сделать что-то вроде этого:
def name
name_trans || name
end
если name_trans
атрибут не равен нулю, затем верните его, иначе верните . Как мне это сделать?
это должно тогда называться обычно так:
@category.name
7 ответов
на Руководство По Стилю Рельсов рекомендует использовать self[:attr]
над read_attribute(:attr)
.
вы можете использовать его как это:
def name
name_trans || self[:name]
end
Update: предпочтительный метод в соответствии с Руководство По Стилю Рельсов использовать self[:name]
вместо read_attribute
и write_attribute
. Я бы посоветовал вам пропустить Мой ответ и вместо этого предпочел этот.
вы можете сделать это именно так, за исключением того, что вам нужно использовать read_attribute
на самом деле получить значение атрибута name и избежать рекурсивного вызова name
способ:
def name
name_trans || read_attribute(:name)
end
Я хотел бы добавить еще один вариант для перезаписи метод getter, который просто: супер.
def name
name_trans || super
end
это работает не только на атрибутах метода геттера, но и на ассоциациях методов геттера, тоже。
переопределение геттера и использование read_attribute
не работает для организаций, но вы можете использовать alias_method_chain
вместо.
def name_with_override
name_trans || name_without_override
end
alias_method_chain :name, :override
если вы используете атрибуты магазина, как это
store :settings, accessors: [:volume_adjustment]
или
используя камни как
hstore_accessor
gem link
таким образом, вы закончили с помощью store
метод на модели, а затем переопределить этот метод, который вы не можете использовать self.read_attribute
, вы должны использовать вместо super
вот так:
def partner_percentage
super.to_i || 10
end
Если кто-то хочет обновить значение после name_trans
в методе геттера вы можете использовать self [: name]=.
def name
self[:name] = name_trans || self[:name]
# don't do this, it will cause endless loop
# update(name: name_trans)
end