dm-aspects 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 899d985e8ae301df81eb7cab303958878d210a5e
4
+ data.tar.gz: 374fcccd14e92a538f71660e0c5d9756deecb673
5
+ SHA512:
6
+ metadata.gz: 7aaf0a05c8e7708562f7b17aabd17254c03f47071f4c21df14b4f19525a4dabe9b5483934ac5079e8c6e9090a4e04d688f681883ac5b2b6a2440eeafc775de23
7
+ data.tar.gz: 546f410612f8ca2963c102faaec179e16b4d710867710b161ebf49b38e436540fb9060199fad137c63ed809ab2b20d75cd90443819627e8f569152c6fdfed6d3
data/.gitignore ADDED
@@ -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 dm-aspects.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Eric Marden
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.
data/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # DataMapper::Aspects
2
+
3
+ Aspect-Oriented modules to add commonly needed methods and properties to your DataMapper models.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'dm-aspects'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ ## Usage
16
+
17
+ ### DataMapper::Aspects::Slug
18
+
19
+ Adds a `:slug` property to your model:
20
+
21
+ property :slug, String, length: 75, unique: true
22
+
23
+ Adds a `find_by_slug` class method to your model.
24
+
25
+ Slug generation is left up to you.
26
+
27
+ Example:
28
+
29
+ ````ruby
30
+ class MyModel
31
+ include DataMapper::Resource
32
+ include DataMapper::Aspects::Slug
33
+
34
+ property :id, Serial
35
+ end
36
+
37
+ MyModel.create(slug: 'my-slug')
38
+ MyModel.find_by_slug('')
39
+ # => #<Game @id=1 @slug="my-slug">
40
+ ````
41
+
42
+ ---
43
+
44
+ ### DataMapper::Aspects::Status
45
+
46
+ Adds a `:status` property to your model that validates it was set to one of the followig options: `'draft'`, `'published'`, `'archived'`. The default value is `'draft'`.
47
+
48
+ You can customize this by overwriting the `statuses` class method on your Model and have it return an array of strings. Just make sure the default status is first element in the array and that none of your statuses are over 50 characters long.
49
+
50
+ We use this module to give admin's simple controls over the visibility of content-oriented objects. This module has helped us avoid conflating domain concerns (validation, state management, content lifecycle, etc) by implementing a state machine on models too early in the development of new applications.
51
+
52
+ Example:
53
+
54
+ ````ruby
55
+ class MyModel
56
+ include DataMapper::Resource
57
+ include DataMapper::Aspects::Status
58
+
59
+ property :id, Serial
60
+ end
61
+
62
+ MyModel.all(status: 'published')
63
+ # => [#<MyModel @id=1 @status='published'>, #<MyModel @id=2 @status='published'>, ...]
64
+ ````
65
+
66
+ Customized `statuses` example:
67
+
68
+ ````ruby
69
+ class MyModel
70
+ include DataMapper::Resource
71
+ include DataMapper::Aspects::Status
72
+
73
+ property :id, Serial
74
+
75
+ def self.statuses
76
+ %w(queued processing processed).freeze
77
+ end
78
+ end
79
+ ````
80
+
81
+ ---
82
+
83
+ ### DataMapper::Aspects::Utils
84
+
85
+ A collection of helper methods to make all your models a little more awesome.
86
+
87
+ Class Methods:
88
+
89
+ - `default_sequence_name` - Returns a string for the sequence name for your model's `Serial` property. PostgreSQL only.
90
+ - `next_id` - Returns the next unused value in your model's `Serial` property sequence. Use this when you need to generate an ID for your model before you've saved the object to the database. Pass it the name of your sequence if it differs from the `default_sequence_name`. PostgreSQL only.
91
+ - `select_options` - Returns an array of hashes containing `:label` and `value` keys. Useful for building a `<select>` form input containing a list of all your objedts. Your model must have a property or method called `name`, which is set as the `label`. The `:value` will be set to your model's `Serial` property (determined automatically) and can be named anything you like.
92
+
93
+ Instance Methods:
94
+
95
+ - `changed?` - Pass it the name of one of your model's properties and it will return a `Boolean` indicating whether or not the field has been changed since you queried it from the database. Use this to avoid performing some expensive operation (like generating a slug, or uploading an image) if the field hasn't changed. Relies on DataMapper's built-in dirty attributes tracking.
96
+ - `attributes_json` - Uses the super-fast `oj` gem to serialize and return a json string of all of your model's attributes.
97
+
98
+ Example:
99
+
100
+ ````ruby
101
+ class Thing
102
+ include DataMapper::Resource
103
+ include DataMapper::Aspects::Utils
104
+
105
+ property :id, Serial
106
+ property :name, String
107
+ end
108
+
109
+
110
+ Thing.default_sequence_name
111
+ # => "things_id_seq"
112
+
113
+ Thing.next_id
114
+ # => 2
115
+
116
+ Thing.select_options
117
+ # => [{:label => 'Thing 1', :value => 1},{:label => 'Thing 2', :value => 1}]
118
+
119
+ thing = Thing.first
120
+ thing.name = 'Thing-a-ma-jig'
121
+ thing.changed?(:name)
122
+ # => true
123
+ thing.save # once your object is persisted, dirty tracking is reset
124
+ thing.changed?(:name)
125
+ # => false
126
+
127
+ Thing.first.attributes_json
128
+ # => '{"id":1,"name":"Thing 1"}'
129
+ ````
130
+
131
+ ## Contributing
132
+
133
+ 1. Fork it ( http://github.com/styleseek/dm-aspects/fork )
134
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
135
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
136
+ 4. Push to the branch (`git push origin my-new-feature`)
137
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ # environment
6
+ ENV['RACK_ENV'] ||= 'development'
7
+
8
+ # load path
9
+ lib_path = File.expand_path('../lib', __FILE__)
10
+ ($:.unshift lib_path) unless ($:.include? lib_path)
11
+
12
+ Rake::TestTask.new do |t|
13
+ t.libs << "spec"
14
+ t.pattern = "spec/**/*_spec.rb"
15
+ end
16
+ task :default => [:test]
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'datamapper/aspects/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "dm-aspects"
9
+ gem.version = DataMapper::Aspects::VERSION
10
+ gem.authors = ['StyleSeek Engineering Team']
11
+ gem.email = ['engineering@styleseek.com']
12
+ gem.summary = %q{Aspect-Oriented modules to add enhance your DataMapper models.}
13
+ gem.description = %q{Aspect-Oriented modules to add commonly needed methods and properties to your DataMapper models.}
14
+ gem.homepage = "https://github.com/styleseek/dm-aspects"
15
+ gem.license = "MIT"
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ["lib"]
21
+
22
+ gem.add_dependency 'dm-core'
23
+ gem.add_dependency 'oj'
24
+
25
+ gem.add_development_dependency "bundler", "~> 1.5"
26
+ gem.add_development_dependency "rake"
27
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module DataMapper
4
+ module Aspects
5
+ module Slug
6
+ def self.included(base)
7
+ base.property :slug, String, length: 75, unique: true
8
+ def base.find_by_slug(slug)
9
+ first(slug: slug, order: [:updated_at.desc])
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module DataMapper
4
+ module Aspects
5
+ module Status
6
+
7
+ def self.statuses
8
+ %w(draft published archived).freeze
9
+ end
10
+
11
+ def self.included(base)
12
+ base.property :status, String, default: ->(r,p) { self.statuses.first }
13
+ base.validates_within :status, set: self.statuses
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ module DataMapper
4
+ module Aspects
5
+ module Utils
6
+ def self.included(base)
7
+ def base.default_sequence_name
8
+ "#{DataMapper::Inflector.pluralize(self.to_s)}_#{self.serial.name}_seq"
9
+ end
10
+
11
+ def base.next_id(sequence = default_sequence_name)
12
+ repository.adapter.select("select nextval('#{sequence}')").first
13
+ end
14
+
15
+ def base.select_options
16
+ all(order: [:updated_at.desc]).map do |object|
17
+ { label: object.name, value: object.send(self.serial.name) }
18
+ end
19
+ end
20
+ end
21
+
22
+ def changed?(property)
23
+ dirty_attribute_names.include?(property)
24
+ end
25
+
26
+ def attributes_json
27
+ @attributes_json ||= Oj.dump(self.attributes, mode: :compat)
28
+ end
29
+
30
+ private
31
+
32
+ def dirty_attribute_names
33
+ dirty_attributes.keys.map { |p| p.name }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ module DataMapper
2
+ module Aspects
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ # encoding: utf-8
2
+
3
+ require 'aspects/slug'
4
+ require 'aspects/status'
5
+ require 'aspects/utils'
6
+ require 'aspects/version'
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dm-aspects
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - StyleSeek Engineering Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-01-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: dm-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Aspect-Oriented modules to add commonly needed methods and properties
70
+ to your DataMapper models.
71
+ email:
72
+ - engineering@styleseek.com
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - dm-aspects.gemspec
83
+ - lib/datamapper/aspects.rb
84
+ - lib/datamapper/aspects/slug.rb
85
+ - lib/datamapper/aspects/status.rb
86
+ - lib/datamapper/aspects/utils.rb
87
+ - lib/datamapper/aspects/version.rb
88
+ homepage: https://github.com/styleseek/dm-aspects
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.2.0
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Aspect-Oriented modules to add enhance your DataMapper models.
112
+ test_files: []