safe_attributes 'address'
def address=(arg)
- write_attribute(:address, arg.to_s.strip)
+ normalized_address = arg.to_s.strip
+
+ # Convert internationalized domain name (IDN) to Punycode
+ # e.g. 'marie@société.example' => 'marie@xn--socit-esab.example'
+ local_part, _at, domain = normalized_address.partition('@')
+ if domain.present?
+ ascii_domain = Addressable::IDNA.to_ascii(domain)
+ normalized_address = "#{local_part}@#{ascii_domain}"
+ end
+
+ write_attribute(:address, normalized_address)
end
def destroy
def test_should_reject_invalid_email
assert_not EmailAddress.new(address: 'invalid,email@example.com').valid?
end
+
+ def test_should_normalize_idn_email_address
+ email = EmailAddress.new(address: 'marie@société.example')
+ assert_equal 'marie@xn--socit-esab.example', email.address
+ assert email.valid?
+ end
end