I set these methods to automatically encrypt values.
class User < ApplicationRecord
def name=(val)
super val.encrypt
end
def name
(super() || '').decrypt
end
When I try to submit the form and there is an error (missing phone), then the name
attribute shows up garbled.
<input class="form-control" type="text" value="Mg8IS1LB2A1efAeZJxIDJMSroKcq6WueyY4ZiUX+hfI=" name="user[name]" id="user_name">
It works when the validations succeeds. It also works in the console when I go line-by-line through my controller #update
.
irb(main):015:0> u = User.find 1
irb(main):016:0> u.name
=> "Sue D. Nym"
irb(main):017:0> u.phone
=> "212-555-1234"
irb(main):018:0> u.update name: 'Sue D. Nym', phone: ''
(10.0ms) BEGIN
(1.0ms) ROLLBACK
=> false
irb(main):020:0> u.save
=> false
irb(main):029:0> u.errors.full_messages.join ','
=> "Phone can't be blank"
irb(main):031:0> u.build_image unless u.image
=> nil
irb(main):033:0> u.name
=> "Sue D. Nym"
users_controller.rb
def update
@user = User.find current_user.id
@user.update user_params
if @user.save
flash.notice = "Profile Saved"
redirect_to :dashboard
else
flash.now.alert = @user.errors.full_messages.join ', '
@user.build_image unless @user.image
render :edit
end
end
The view is somehow getting the encrypted value without going through #name
, and only after a validation failure.
I reduced the controller to the absolute minimum and it fails immediately after #update
. However, it's working on the console!
def update
@user = User.find current_user.id
@user.update user_params
render :edit
return
I reduced my view to the absolute minimum and it shows the name, but only outside of form_for
. I don't know why yet.
edit.haml
[email protected]
=form_for @user, html: { multipart: true } do |f|
=f.text_field :name
HTML source
<span>Sue D. Nym</span>
<form class="edit_user" id="edit_user_1" enctype="multipart/form-data" action="/users/1" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓"><input type="hidden" name="_method" value="patch"><input type="hidden" name="authenticity_token" value="C/ScTxfENNxCKgzG0qAlPElOKI7nOYxZimQ7BsB64wIWQ9El4+vOAfxX3qHL08rbr0sxRiJnzQti13e4DAgkfQ==">
<input type="text" value="sER9cjwa6Ov5weXjEQN2KJYoTOXtVBytpX/cI/aPrFs=" name="user[name]" id="user_name">
</form>
I noticed attributes
still returned encrypted values so I tried adding this but form_for
still manages to obtain the encrypted value and put it in the form!
def attributes
attr_hash = super()
attr_hash["name"] = name
attr_hash
end
Rails 5.0.2
encrypted_field
, and it is just like the answer below, except it switches to useencrypted_name
as the real field and a virtualname
method instead ofdecrypted_name
. – Sperling