assignable_types.rb 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. module AssignableTypes
  2. extend ActiveSupport::Concern
  3. included do
  4. validate :validate_type
  5. end
  6. def short_type
  7. @short_type ||= type.split("::").pop
  8. end
  9. def validate_type
  10. errors.add(:type, "cannot be changed once an instance has been created") if type_changed? && !new_record?
  11. errors.add(:type, "is not a valid type") unless self.class.valid_type?(type)
  12. end
  13. module ClassMethods
  14. def load_types_in(module_name, my_name = module_name.singularize)
  15. const_set(:MODULE_NAME, module_name)
  16. const_set(:BASE_CLASS_NAME, my_name)
  17. const_set(:TYPES, Dir[Rails.root.join("app", "models", module_name.underscore, "*.rb")].map { |path| module_name + "::" + File.basename(path, ".rb").camelize })
  18. end
  19. def types
  20. const_get(:TYPES).map(&:constantize)
  21. end
  22. def valid_type?(type)
  23. const_get(:TYPES).include?(type)
  24. end
  25. def build_for_type(type, user, attributes = {})
  26. attributes.delete(:type)
  27. if valid_type?(type)
  28. type.constantize.new(attributes).tap do |instance|
  29. instance.user = user if instance.respond_to?(:user=)
  30. end
  31. else
  32. const_get(:BASE_CLASS_NAME).constantize.new(attributes).tap do |instance|
  33. instance.type = type
  34. instance.user = user if instance.respond_to?(:user=)
  35. end
  36. end
  37. end
  38. end
  39. end