Skip to content

Instantly share code, notes, and snippets.

@fj
Last active July 29, 2017 04:28
Show Gist options
  • Save fj/8243261 to your computer and use it in GitHub Desktop.
Save fj/8243261 to your computer and use it in GitHub Desktop.
# In a context somewhere, we'd like to do this:
u = User.new
u.extend Passworded
# Unfortunately, this doesn't work:
module Passworded
include ActiveModel::Model # Can't do this because ActiveModel::Model wants to be included
# on classes, not modules.
# Also can't remove it, because if you do then your validation
# methods aren't defined.
attr_accessor :password
attr_accessor :password_confirmation
validates :password, :presence => true, :confirmation => true
validates :password_confirmation, :presence => true
end
@saturnflyer
Copy link

You need to handle the inclusion of the module.

module Passworded
  def self.extended(base)
    base.singleton_class.send(:include, ActiveModel::Model)
  end
  #…
end

This should include ActiveModel::Model in the singletonclass of the u object that you have.
ActiveModel uses the included hook to add it's features and while the alternative of base.extend ActiveModel::Model is usually semantically the same thing, it doesn't run the included hook so you have to specifically add it to the singleton_class.

But I've not yet found a need to do validation of data like this by extending an object.

Do you have contextual differences in validation schemes when storing data?

@fj
Copy link
Author

fj commented Jan 3, 2014

@saturnflyer Yeah, I need to run "expert user" vs. "non-expert user" validations on a OptionsContract model. Some validations always apply (those go on the model), some apply when a non-expert user wants to make changes, and some apply when an expert user wants to make changes.

I'll give this a shot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment