Skip to content

Instantly share code, notes, and snippets.

@Sutto
Created November 15, 2008 12:59
Show Gist options
  • Select an option

  • Save Sutto/25241 to your computer and use it in GitHub Desktop.

Select an option

Save Sutto/25241 to your computer and use it in GitHub Desktop.
module ModelExtensions
# A set of extensions to add handy can_has-style extensions for
# classes. Based on code by Fowlduck and Faithfulgeek pasted in
# #offrails.
def can_has(*args)
options = args.extract_options!
components = _flatten_parameters(args)
components += _flatten_parameters(options)
components = components.map { |c| File.join(self.name.underscore, c) }
components.each do |c|
file = File.join(Rails.root, "app/behaviours", c)
if File.exist?(file + ".rb")
require file
klass = File.join("can_has_extensions", c).camelize.constantize
# Include the appropriate modules.
include klass::InstanceMethods if defined?(klass::InstanceMethods)
extend klass::ClassMethods if defined?(klass::ClassMethods)
# Call implemented! if the method exists.
klass.implemented!(self) if klass.respond_to?(:implement!)
else
Rails.logger.warn "Couldn't load behaviour for #{c.camelize} - File not found at #{file}.rb"
end
end
end
private
# Recursively flattens the parameters and extracts paths etc.
def _flatten_parameters(item, prefix = "")
extras = []
if item.is_a?(Hash)
extras = item.map do |k,v|
extras = _flatten_parameters(v).map { |i| File.join(k.to_s, i) }
end
elsif item.is_a?(Array)
extras = item.map { |i| i.to_s }
else
extras = [item.to_s]
end
extras = extras.map { |v| File.join(prefix, v) } unless prefix.blank?
return extras.flatten
end
end
require 'model_extensions'
class X
extend ModelExtensions
can_has 'something', 'user' => 'demo'
end
Will try and load CanHasExtensions::X::Something and CanHasExtensions::X::User::Demo
located at app/behaviours/x/something.rb and app/behaviours/x/user/demo.rb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment