Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ActiveModel::Dirty support not working #335

Open
aidandamerell opened this issue Jan 30, 2019 · 2 comments
Open

ActiveModel::Dirty support not working #335

aidandamerell opened this issue Jan 30, 2019 · 2 comments

Comments

@aidandamerell
Copy link

The attribute_was method does not appear to return the old value from an encrypted value:

class Person < ApplicationRecord
	attr_encrypted :email, key: "Some key"
	before_update :check

	private

	def check
		puts "Old: #{self.email_was}"
		puts "New: #{self.email}"
	end
end

This can be seen in the console:

2.5.3 :006 > Person.first.email
 => "[email protected]"
2.5.3 :006 > Person.first.update(email: "[email protected]")
Old: 
New: [email protected]
=> true
@klappradla
Copy link

klappradla commented Feb 28, 2019

I ran into a similar problem when using attr_encrypted in combination with the bind_index gem: the way attr_encryptor defines the setter for the to be encrypted attribute, it only assigns the instance variable, not the attribute the way rails would do it using []= or the protected alternative write_attributes alternative.

Doing so, the changes object of the record won't be populated and therefore the attribute does not appear to have been changed.

This is the respective code in attr_encrypted:

define_method("#{attribute}=") do |value|

(here for quicker reading:)

define_method("#{attribute}=") do |value|
  send("#{encrypted_attribute_name}=", encrypt(attribute, value))
  instance_variable_set("@#{attribute}", value)
end

If I adapt this to closer resemble what Rails' internal attribute= method does, it could look like this:

define_method("#{attribute}=") do |value|
  send("#{encrypted_attribute_name}=", encrypt(attribute, value))
  send("[#{attribute}]=", value)
  instance_variable_set("@#{attribute}", value)
end

This setter implementation would actually assign the attribute. Changes to the attribute will appear in the object's changes hash and things like <attribute>.changed? would work same as for "normal" non-encrypted attributes. But I'm not sure if there's not more to it (did not yet dive into the details for ActiveModel::Dirty)...

I wasn't sure if this is actually intended by the authors 🤔
If not, I'd be happy to craft out a PR to change this, but this may also already be addressed in #337 💚

@surjay
Copy link

surjay commented Mar 22, 2019

Any traction on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants