ruby/ruby — pull request #581 by AndyObtiva (2014-03-27 23:31:12+00:00)
Title: Added super_module allows a module to define and invoke class methods like a superclass

# super_module
### allows a module to define and invoke class methods the same way a superclass does

Documentation by Annas Al Maleh (a.k.a. Andy Maleh)

SuperModule allows defining and invoking class methods just like a superclass by doing so in the
module definition body. This removes the need to delay the definition and invocation of class methods
via self.included(base)

Using SuperModule therefore facilitates writing correct mixin code that is easily and productively
maintainable by following the same familiar semantics of superclass code definition.

SuperModule does support module dependencies by allowing a module to include other modules, even if
they depend on base class methods. This achieves better visibility and maintainability of module
dependencies.

To use, simply include SuperModule at the top of a module definition body, and then follow it by
including other module dependencies if needed, base class method invocations, base class method
definitions, and instance method definitions.

The following serves as a nice example for the use of SuperModule:

require 'super_module'

module UserIdentifiable
include SuperModule

belongs_to :user
validates :user_id, presence: true

def self.most_active_user
User.find_by_id(select('count(id) as head_count, user_id').group('user_id').order('count(id) desc').first.user_id)
end

def slug
"#{self.class.name}_#{id}_user_#{user_id}"
end
end

class ClubParticipation < ActiveRecord::Base
include UserIdentifiable
end

class CourseEnrollment < ActiveRecord::Base
include UserIdentifiable
end

module Accountable
include SuperModule
include UserIdentifiable
end

class Activity < ActiveRecord::Base
include Accountable
end

CourseEnrollment.most_active_user
ClubParticipation.most_active_user
Activity.last.slug
ClubParticipation.create(club_id: club.id, user_id: user.id).slug
CourseEnrollment.new(course_id: course.id).valid?

## Notes

SuperModule was designed to be used in the code definition of a module and must be included
at the very top of the body definition before including any other modules

As with regular module inclusion in a base class, make sure any methods that the "super module"
(module enhanced with SuperModule) depends on have been defined in the class or superclass
above (before) the inclusion of the "super module".

Also available as a separate project on GitHub: https://github.com/AndyObtiva/super_module