activerecord-concernable 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in activerecord-concernable.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Blake Taylor
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,83 @@
1
+ # Activerecord::Concernable
2
+
3
+ A DSL for defining ActiveRecord concerns.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'activerecord-concernable'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install activerecord-concernable
18
+
19
+ ## Usage
20
+
21
+ The Concernable DSL is available within any ActiveRecord::Base. The DSL consist
22
+ of a single command `concern`. Use it to define concerns for the object. The
23
+ body of the concern follows the same rules that of [ActiveSupport::Concern][1].
24
+
25
+ Defining concerns:
26
+
27
+ class Notification < ActiveRecord::Base
28
+
29
+ belongs_to :user
30
+ belongs_to :notifiable, polymorphic: true
31
+
32
+ # Extend user with has_many :notifications. When concern is passed a class
33
+ # the generated concern will automatically be mixed into that class.
34
+ concern User do
35
+ included do
36
+ has_many :notifications
37
+ end
38
+ end
39
+
40
+ # Create a named concern by passing a symbol. Mix into any number of
41
+ # classes by passing them as `:of` in the options hash.
42
+ concern :notifiable, of: [Comments, Posts] do
43
+ included do
44
+ has_many :notifications, as: :subject, dependent: :destroy
45
+ end
46
+
47
+ def create_notification(message)
48
+ notifications.create(message: message)
49
+ end
50
+ end
51
+ end
52
+
53
+ ### Why would I want to do this?
54
+
55
+ The primary reason for using the DSL is to keep ActiveRecord models skinny and
56
+ well defined, and to avoid the inevitability of monolithic model object (1000
57
+ line user.rb anyone?).
58
+
59
+ The idea is that as new models are introduced, they will often be related, and
60
+ therefore "concerned" with other models in the system. To a large extent, this
61
+ is the very point of relational data and ActiveRecord. Unfortunately, This
62
+ creates pain points at the cruxes of the domain model. New objects are concerned
63
+ with the popular objects, and the popular objects accumulate the inverse
64
+ concerns and functionality.
65
+
66
+ Concern modules can solve this problem is by allowing you to avoid adding
67
+ additional code to the centralized definition of the core class when adding a
68
+ new associated class. Instead, you simply add a concern and mix it in.
69
+
70
+ This is essentially what the DSL does, but takes things a few steps further, by
71
+ allowing you to easily nest the concern definition right inside the dependent
72
+ model and then mix into the dependant classes unobtrusively.
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create new Pull Request
81
+
82
+
83
+ [1]: http://api.rubyonrails.org/classes/ActiveSupport/Concern.html
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'activerecord-concernable/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "activerecord-concernable"
8
+ gem.version = Activerecord::Concernable::VERSION
9
+ gem.authors = ["Blake Taylor"]
10
+ gem.email = ["blakefrost@gmail.com"]
11
+ gem.description = %q{A DSL for defining ActiveRecord concerns}
12
+ gem.summary = %q{
13
+ Helps keep models skinny and code understandable by making it simple to
14
+ define concerns and mix them into the affect class right from within the
15
+ concerned class. See readme for more information.
16
+ }
17
+ gem.homepage = ""
18
+
19
+ gem.files = `git ls-files`.split($/)
20
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
+ gem.require_paths = ["lib"]
23
+
24
+ gem.add_dependency('activerecord')
25
+ gem.add_development_dependency('rake')
26
+ end
@@ -0,0 +1,67 @@
1
+ require "activerecord-concernable/version"
2
+
3
+ module ActiveRecord
4
+ module Concernable
5
+ # Defines a concern.
6
+ #
7
+ # Concern will be named by convention below the ::Concerns module. Concern
8
+ # will be wrapped in namespace named by convention from the class defining the
9
+ # concern. For example, a User concern within the Notification class would
10
+ # be available at ::Concerns::Notification::User
11
+ #
12
+ # By convention, if a class is passed as the concern name, the concern will be
13
+ # automatically mixed into the passed class. If this functionality is not
14
+ # desirable, pass the name as a symbol i.e. :user.
15
+ #
16
+ # To mix into additional classes, pass them classes as an array to the of
17
+ # option key.
18
+ #
19
+ # Example:
20
+ #
21
+ # class Notification
22
+ # extend Concernable
23
+ #
24
+ # concern :user do
25
+ # included do
26
+ # has_many :notifications
27
+ # end
28
+ # end
29
+ #
30
+ # concern :notifiable, of: [Comments, Posts] do
31
+ # include do
32
+ # has_many :notifications, as: :subject, dependent: :destroy
33
+ # end
34
+ #
35
+ # def create_notifcation(*args)
36
+ # notications.create(*args)
37
+ # end
38
+ # end
39
+ # end
40
+ #
41
+ def concern(name, opts={}, &block)
42
+ namespace = self.to_s.split('::').reduce(::Concerns) do |namespace, module_name|
43
+ namespace.const_defined?(module_name, false) ? namespace.const_get(module_name) : namespace.const_set(module_name, Module.new)
44
+ end
45
+
46
+ # Create and populate concern module.
47
+ camelized_name = name.to_s.camelize
48
+ concern = Module.new
49
+ concern.send(:extend, ActiveSupport::Concern)
50
+ concern.class_eval(&block)
51
+ concern = namespace.const_set(camelized_name, concern)
52
+
53
+ # Mix-in concern
54
+ opts.symbolize_keys!
55
+ opts[:of] = Array(opts[:of])
56
+ opts[:of] << name if name.instance_of? Class
57
+ Array(opts[:of]).each { |klass| klass.send(:include, concern) }
58
+ end
59
+
60
+ end
61
+ end
62
+
63
+ # Defines namespace for where concerns will be defined to.
64
+ module Concerns; end
65
+
66
+ # Extend Active Record Base with Concernable.
67
+ ActiveRecord::Base.extend ActiveRecord::Concernable
@@ -0,0 +1,5 @@
1
+ module Activerecord
2
+ module Concernable
3
+ VERSION = "0.4.0"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,93 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activerecord-concernable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Blake Taylor
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activerecord
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: A DSL for defining ActiveRecord concerns
47
+ email:
48
+ - blakefrost@gmail.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - activerecord-concernable.gemspec
59
+ - lib/activerecord-concernable.rb
60
+ - lib/activerecord-concernable/version.rb
61
+ homepage: ''
62
+ licenses: []
63
+ post_install_message:
64
+ rdoc_options: []
65
+ require_paths:
66
+ - lib
67
+ required_ruby_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ segments:
74
+ - 0
75
+ hash: 1236418441682571541
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ segments:
83
+ - 0
84
+ hash: 1236418441682571541
85
+ requirements: []
86
+ rubyforge_project:
87
+ rubygems_version: 1.8.23
88
+ signing_key:
89
+ specification_version: 3
90
+ summary: Helps keep models skinny and code understandable by making it simple to define
91
+ concerns and mix them into the affect class right from within the concerned class.
92
+ See readme for more information.
93
+ test_files: []