https://github.com/ledermann/unread
全体像
├── .gemtags
├── .gitignore
├── .tags
├── .tags_sorted_by_file
├── .travis.yml
├── Gemfile
├── Gemfile.lock
├── MIT-LICENSE
├── README.md
├── Rakefile
├── ci
│ ├── Gemfile-rails-3-0
│ ├── Gemfile-rails-3-1
│ ├── Gemfile-rails-3-2
│ ├── Gemfile-rails-4-0
│ └── Gemfile-rails-4-1
├── lib
│ ├── generators
│ │ └── unread
│ │ └── migration
│ │ ├── migration_generator.rb
│ │ └── templates
│ │ └── migration.rb
│ ├── unread
│ │ ├── base.rb
│ │ ├── read_mark.rb
│ │ ├── readable.rb
│ │ ├── reader.rb
│ │ ├── scopes.rb
│ │ └── version.rb
│ └── unread.rb
├── spec
│ ├── base_spec.rb
│ ├── model
│ │ ├── email.rb
│ │ └── reader.rb
│ ├── read_mark_spec.rb
│ ├── readable_spec.rb
│ ├── spec_helper.rb
│ └── support
│ ├── matchers
│ │ └── perform_queries.rb
│ ├── query_counter.rb
│ └── timecop.rb
└── unread.gemspec
11 directories, 34 files
普通のgenerators
#lib/unread.rb
ActiveRecord::Base.send :include, Unread
lib/unread/*をrequireし最後にActiveRecord::Baseにmixinしている
#lib/unread/base.rb
ActiveRecord::Baseへに追加するクラスメソッドの定義をしている 追加されるクラスメソッドは2つ ::acts_as_reader ::acts_as_readable
def acts_as_reader
ReadMark.belongs_to :user, :class_name => self.to_s
has_many :read_marks, :dependent => :delete_all, :foreign_key => 'user_id', :inverse_of => :user
after_create do |user|
# We assume that a new user should not be tackled by tons of old messages
# created BEFORE he signed up.
# Instead, the new user starts with zero unread messages
(ReadMark.readable_classes || []).each do |klass|
klass.mark_as_read! :all, :for => user
end
end
include Reader::InstanceMethods
end
def acts_as_readable(options={})
class_attribute :readable_options
options.reverse_merge!(:on => :updated_at)
self.readable_options = options
has_many :read_marks, :as => :readable, :dependent => :delete_all
ReadMark.readable_classes ||= []
ReadMark.readable_classes << self unless ReadMark.readable_classes.include?(self)
include Readable::InstanceMethods
extend Readable::ClassMethods
extend Readable::Scopes
end
モデルに::acts_as_readerが宣言されたときにinclude Reader::InstanceMethodsされ使用できるメソッドが増える仕組みになっている 宣言系メソッドの実装はその内部で宣言後に使用可能になるメソッドを定義したmoduleをincludeするパターンが多い
class User < ActiveRecord::Base
acts_as_reader
end
#lib/unread/reader.rb Reader::InstanceMethodsの実装 #lib/unread/readable.rb Readable::InstanceMethodsとReadable::ClassMethodsの実装 #lib/unread/scopes.rb Readable::Scopesの実装
#lib/read_mark.rb ActiveRecord::Baseを継承するこのgemが追加するテーブルのモデルクラスを定義している