У меня есть модель User
, где я включаю номер мобильного телефона. Номер мобильного телефона будет сохранен в базе данных в международном формате. Поскольку пользователи часто не знают об этом и не любят международные форматы, я сменил геттер и сеттеры, чтобы пользователь мог вводить цифры в локальном формате, и они отображают локальный формат, если международный префикс отсутствует.Странные вещи случаются, когда я переоцениваю геттеры и сеттеры моей модели ActiveRecord
class User < ActiveRecord::Base
def mobile=(number)
# Strip whitespace, dashes and slashes first
[" ", "-", "/", "\\"].each do |particle|
number.gsub!(particle, "")
end
# Check if there is leading 00, this indicates a
# country code.
number.gsub!(/^00/,"+")
# Check if there is only one leading zero. If there is,
# treat as German number
number.gsub!(/^0/,"+49")
# Now write to attribute. Validate later.
puts "Writing: #{number}"
write_attribute(:mobile, number)
end
def mobile
number = read_attribute(:mobile)
puts "Reading: #{number}"
# If this is a German number, display as local number.
number.gsub!(/\+49/,"0")
number
end
end
Теперь кажется, что это работает не так, как ожидалось. Это моя rails console
сессия:
> u = User.new(:mobile => "0163 12345")
Writing: +4916312345
=> #<User id: nil, mobile: "+4916312345", ...>
Это работает, как ожидалось. Итак, давайте проверим геттер:
> u.mobile
Reading: +4916312345
=> "016312345"
Выглядит хорошо. Но лучше проверить его еще раз:
> u.mobile
Reading: 016312345
=> "016312345"
WTF? Мой атрибут изменился. Ограничено ли это функцией геттера?
> u
=> #<User id: nil, mobile: "016312345", ...>
Нет. Он устанавливает атрибут даже в модели базы данных.
Если я дважды получаю доступ к атрибуту, атрибут изменяется. Я не получил доступ к write_attribute
. Почему меняется мой атрибут?
Почему вы делаете это здесь, а не в валидаторе или в фильтре 'before_save'? –
рельсы версия вы используете? – efoo