manhattan 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,143 @@
1
+ # Manhattan
2
+
3
+ Manhattan is a gem extracted from the practices we used at [Xenda](http://xenda.pe "Xenda") in the development of our projects.
4
+
5
+ It strives to be a simple status manager for models with minimal overhead and allowing the creation of a simple state machine. Most projects in our experience need for a model to hold a status at once and to perform some actions before or after obtaining that state. This gem simplifies that work without adding much overhead.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'manhattan'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install manhattan
20
+
21
+ ## Usage
22
+
23
+ Models that want to be handled by Manhattan should include the gem on their definition:
24
+
25
+ ```ruby
26
+ class ComicBook < ActiveRecord::Base
27
+ include Manhattan
28
+ end
29
+ ```
30
+
31
+ Manhattan will then wait for your to describe the list of states your class can hold:
32
+
33
+ ```ruby
34
+ class ComicBook < ActiveRecord::Base
35
+ include Manhattan
36
+
37
+ has_statuses :opened, :sold
38
+
39
+ end
40
+ ```
41
+
42
+ For it to do its work, it'll assume the model has a "status" column of type string on your database. This can be customized by appending the "column_name" key at the end of your states list:
43
+
44
+ ```ruby
45
+ class ComicBook < ActiveRecord::Base
46
+ include Manhattan
47
+
48
+ has_statuses :opened, :sold, column_name: :state
49
+
50
+ end
51
+ ```
52
+
53
+ Manhattan will even allow you to setup a default state for initialized records. Take notice that this shouldn't be used instead of setting a default value on a migration or directly on your column.
54
+
55
+ After this setup, Manhattan will give you some love in the form of code
56
+
57
+ #### Getting a list of status
58
+
59
+ ```ruby
60
+ ComicBook.statuses #=> ["opened", "sold"]
61
+ ComicBook.new.statuses #=> ["opened", "sold"]
62
+ ```
63
+
64
+ #### Setting a new status
65
+
66
+ ```ruby
67
+ comic_book = ComicBook.new
68
+ comic_book.mark_as_opened
69
+ comic_book.status #=> "opened"
70
+ ```
71
+
72
+ #### Querying about its status
73
+
74
+ ```ruby
75
+ # directly asking for status
76
+ comic_book.opened? #=> "true"
77
+ comic_book.sold? #=> "false"
78
+
79
+ # or even asking about its negative
80
+ comic_book.unopened? #=> "false"
81
+ comic_book.not_sold? #=> "true"
82
+ ```
83
+
84
+ Manhattan will create alias like "invalid" "unsold" and "not_valid" for each state. Use whichever feels natural for your code.
85
+
86
+ #### Performing actions before and after code changes
87
+
88
+ Manhattan will look for before_* and after_* methods for each state. If they exist, it will run them accordingly:
89
+
90
+ ```ruby
91
+ class ComicBook < ActiveRecord::Base
92
+ # .... all the above code
93
+
94
+ def before_opened
95
+ puts "This is a sad day... when this comic loses its value"
96
+ end
97
+
98
+ def after_opened
99
+ puts "WE CRY NOW AND SHIVER FOR IT'S NO LONGER COLLECTABLE"
100
+ end
101
+ ```
102
+
103
+ ```ruby
104
+ comic_book.mark_as_opened #=>
105
+ #"This is a sad day... when this comic loses its value"
106
+ #"WE CRY NOW AND SHIVER FOR IT'S NO LONGER COLLECTABLE"
107
+ ````
108
+
109
+ #### Model scopes
110
+
111
+ Each model class has associated scopes created for easy returning records from the DB for each state:
112
+
113
+ ```ruby
114
+ ComicBook.opened #=> select * from comic_books where status = 'opened'
115
+ ```
116
+
117
+ #### Adding a default state
118
+
119
+ If wanted, you can setup a default state for your model
120
+
121
+ ```ruby
122
+ class ComicBook < ActiveRecord::Base
123
+ include Manhattan
124
+
125
+ has_statuses :opened, :sold, default_value: :opened
126
+ end
127
+ ```
128
+
129
+ ```ruby
130
+ ComicBook.new.status #=> "opened"
131
+ ```
132
+
133
+ ## TODO
134
+
135
+ Fairly simple, but I18N is pending.
136
+
137
+ ## Contributing
138
+
139
+ 1. Fork it
140
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
141
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
142
+ 4. Push to the branch (`git push origin my-new-feature`)
143
+ 5. Create new Pull Request
@@ -3,6 +3,7 @@ require "manhattan/version"
3
3
  module Manhattan
4
4
 
5
5
  extend ActiveSupport::Concern
6
+ class AlreadyDefinedMethod < StandardError; end
6
7
 
7
8
  def status_column_value
8
9
  self.send(self.class.status_column_name)
@@ -39,6 +40,10 @@ module Manhattan
39
40
  def has_statuses(*statuses)
40
41
  options = statuses.pop if statuses.last.is_a? Hash
41
42
  options ||= {}
43
+
44
+ common_methods = statuses & self.methods
45
+ raise Manhattan::AlreadyDefinedMethod, "Already defined method #{common_methods}" unless common_methods.empty?
46
+
42
47
  @status_column_name = options[:column_name]
43
48
  @status_column_name ||= :status
44
49
 
@@ -81,9 +86,9 @@ module Manhattan
81
86
  def define_query_methods(status)
82
87
 
83
88
  status_sym = status.to_sym
84
- query = "#{status}?".to_sym
85
- negative_query = "not_#{query}".to_sym
86
- alternative_negatives = ["un#{query}".to_sym, "in#{query}".to_sym]
89
+ query = "is_#{status}?".to_sym
90
+ negative_query = "is_not_#{status}?".to_sym
91
+ alternative_negatives = ["is_un#{status}?".to_sym, "is_in#{status}?".to_sym]
87
92
 
88
93
  define_method query do
89
94
  status_column_value == status_value(status_sym)
@@ -1,3 +1,3 @@
1
1
  module Manhattan
2
- VERSION = "0.0.3"
2
+ VERSION = "0.0.4"
3
3
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: manhattan
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.0.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Alvaro Pereyra
@@ -16,7 +16,7 @@ dependencies:
16
16
  requirements:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
- version: 3.2.10
19
+ version: '3.2'
20
20
  none: false
21
21
  name: rails
22
22
  type: :runtime
@@ -25,23 +25,7 @@ dependencies:
25
25
  requirements:
26
26
  - - ~>
27
27
  - !ruby/object:Gem::Version
28
- version: 3.2.10
29
- none: false
30
- - !ruby/object:Gem::Dependency
31
- version_requirements: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - ! '>='
34
- - !ruby/object:Gem::Version
35
- version: '0'
36
- none: false
37
- name: sqlite3
38
- type: :development
39
- prerelease: false
40
- requirement: !ruby/object:Gem::Requirement
41
- requirements:
42
- - - ! '>='
43
- - !ruby/object:Gem::Version
44
- version: '0'
28
+ version: '3.2'
45
29
  none: false
46
30
  description: Easy way to define states on your classes
47
31
  email:
@@ -55,7 +39,7 @@ files:
55
39
  - lib/tasks/manhattan_tasks.rake
56
40
  - MIT-LICENSE
57
41
  - Rakefile
58
- - README.rdoc
42
+ - README.md
59
43
  homepage: ''
60
44
  licenses: []
61
45
  post_install_message:
@@ -1,29 +0,0 @@
1
- # Manhattan
2
-
3
- TODO: Write a gem description
4
-
5
- ## Installation
6
-
7
- Add this line to your application's Gemfile:
8
-
9
- gem 'manhattan'
10
-
11
- And then execute:
12
-
13
- $ bundle
14
-
15
- Or install it yourself as:
16
-
17
- $ gem install manhattan
18
-
19
- ## Usage
20
-
21
- TODO: Write usage instructions here
22
-
23
- ## Contributing
24
-
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request