User
携帯電話番号を入れたモデルがあります。携帯電話番号は国際形式でデータベースに保存されます。ユーザーはこれに気付かず、国際形式が気に入らないことが多いため、国際プレフィックスがない場合にユーザーがローカル形式で数値を入力し、ローカル形式が表示されるように、ゲッターとセッターを変更しました。
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", ...>
いいえ。データベースモデルでも属性を設定します。
属性に2回アクセスすると、属性が変更されます。アクセスしませんでしwrite_attribute
た。属性が変わるのはなぜですか?