jeudi 5 janvier 2017

Rails - Temporarily update active record object

Is there a way to transform model attributes temporarily in a different format but preserve the original value when requested again?

Here's an example of the model:

class User < ActiveRecord::Base
  has_many :emails, 
    order: "sent_at desc, id desc", 
    dependent: :destroy, 
    inverse_of: :user

  def sanitized_emails
    emails.map do |e|
      e.assign_attributes({body: Sanitize.fragment(e.body)})
      e
    end
  end
end

Basically I want to be able to run user.sanitized_emails and have the body sanitized, but when running user.emails again, the values are saved and require a reload. Is there a way to avoid this so that the data is only transformed for the return value of the sanitized_emails method?

Better yet, is there a way to add this method to the emails model?

class Email < ActiveRecord::Base
  # ...
  def with_sanitized_body
    update_attribute :body, Sanitize.fragment(body)
    self
  end
end

Something like the above, so that I can run user.emails.map(&:with_sanitized_body), so that the concern is removed from the user model. I still want to be able to run user.emails immediately after and expect body to contain its original value.

I feel like this should be simple and that I'm missing something obvious :/

Aucun commentaire:

Enregistrer un commentaire