Как перезаписать метод 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

вы можете использовать метод Rails read_attribute. Rails docs