dm-aspects 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +137 -0
- data/Rakefile +16 -0
- data/dm-aspects.gemspec +27 -0
- data/lib/datamapper/aspects/slug.rb +14 -0
- data/lib/datamapper/aspects/status.rb +17 -0
- data/lib/datamapper/aspects/utils.rb +37 -0
- data/lib/datamapper/aspects/version.rb +5 -0
- data/lib/datamapper/aspects.rb +6 -0
- metadata +112 -0
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
data/Gemfile
ADDED
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]
|
data/dm-aspects.gemspec
ADDED
@@ -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
|
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: []
|