attr_publish 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 987c18de5f5bed476683cae2628e4742c069e130
4
+ data.tar.gz: 87a8c39cedb1bbc000ccc711f044fe5d2d8d1c54
5
+ SHA512:
6
+ metadata.gz: c941855591f4af93280483bf83f97f2f066b5b6819e1fd0fb86b158b1870011b4d4c17bb21ad72a100345dbb513487141ccee1bbc1de8137b40efbd2f1c6b232
7
+ data.tar.gz: a2df86692d6996fd2d8ed6d040fc34729a721b82615cd953f5cde710b5e5e05ce23e08db15e1b4dbc8a21f4d25b59ac376ca1388c3acf585cf5142504ed68d88
@@ -0,0 +1,4 @@
1
+ # Change Log
2
+
3
+ ## v1.0.0
4
+ - Initial release.
@@ -0,0 +1,136 @@
1
+ # AttrPublish
2
+
3
+ Provides scopes for finding published and unpublished items, and (for date/datetime published columns) for returning recent or upcoming items. Also provides a set of convenient instance methods for publishing and unpublishing a record.
4
+
5
+ Allows a given boolean, date, or datetime column to indicate whether a model object is published. A boolean published column is just an on/off flag. A date/datetime column requires the value of published column to be before "current" for the object to be published.
6
+
7
+ AttrPublish is extracted from the Brightcommerce platform and is in use by several projects.
8
+
9
+ ## Installation
10
+
11
+ To install add the line to your Gemfile:
12
+
13
+ ``` ruby
14
+ gem 'attr_publish'
15
+ ```
16
+
17
+ And `bundle install`.
18
+
19
+ ## How To Use
20
+
21
+ To add AttrPublish to a model, include the concern:
22
+
23
+ ``` ruby
24
+ class Post < ActiveRecord::Base
25
+ include AttrPublish
26
+
27
+ attr_publish
28
+ end
29
+ ```
30
+
31
+ This will automatically default to look for a column named ':published'.
32
+
33
+ To autoload AttrPublish for all models, add the following to an initializer:
34
+
35
+ ``` ruby
36
+ require 'attr_publish/active_record'
37
+ ```
38
+
39
+ You then don't need to `include AttrPublish` in any model, but you still need to add the `attr_publish` class method.
40
+
41
+ ### Class Methods
42
+
43
+ AttrPublish adds the following scopes to your model (using the previous example model `Post`):
44
+
45
+ ``` ruby
46
+ Post.published
47
+ Post.unpublished
48
+ ```
49
+
50
+ By default these scopes uses the current date or current time to limit the query. However, you can pass any date or datetime to these scopes to limit the records it returns:
51
+
52
+ ``` ruby
53
+ Post.published(DateTime.yesterday)
54
+ ```
55
+
56
+ If the published column is of type `:date` or `:datetime` the following additional scopes are provided:
57
+
58
+ ``` ruby
59
+ Post.recent
60
+ Post.upcoming
61
+ ```
62
+
63
+ By default these scopes return all matching records. You can limit the number of records returned by passing a number to the scope:
64
+
65
+ ``` ruby
66
+ Post.recent(10) # returns the 10 most recent published posts (ordered by date or datetime)
67
+ Post.upcoming(3) # returns 3 next unpublished posts (ordered by date or datetime)
68
+ ```
69
+
70
+ ### Instance Methods
71
+
72
+ AttrPublish automatically provides the following class instance methods:
73
+
74
+ - `published?`
75
+ - `unpublished?`
76
+ - `publish`
77
+ - `publish!`
78
+ - `unpublish`
79
+ - `unpublish!`
80
+
81
+ If the column type is specified as a Date or Time, you can pass a datetime parameter to the `publish` and `publish!` instance methods. `publish` and `unpublish` methods will change the instance's publish value, but won't save the object. Using the `publish!` and `unpublish!` bang methods will call save (commit) after changing the value.
82
+
83
+ ### Setup
84
+
85
+ Add the model attribute you want to use with AttrPublish in your migration:
86
+
87
+ ``` ruby
88
+ class CreatePosts < ActiveRecord::Migration[5.2]
89
+ def change
90
+ create_table :posts do |table|
91
+ table.column :published, :datetime
92
+ table.timestamps
93
+ end
94
+ end
95
+ end
96
+ ```
97
+
98
+ You can change the column used by AttrPublish by adding the column name to the `attr_publish` class method:
99
+
100
+ ``` ruby
101
+ class Post < ApplicationRecord
102
+ include AttrPublish
103
+
104
+ attr_publish :published_on
105
+ end
106
+ ```
107
+
108
+ ## Dependencies
109
+
110
+ AttrPublish gem has the following runtime dependencies:
111
+ - activerecord >= 5.1.4
112
+ - activesupport >= 5.1.4
113
+
114
+ ## Compatibility
115
+
116
+ Tested with MRI 2.4.2 against Rails 5.2.2.
117
+
118
+ ## Contributing
119
+
120
+ 1. Fork it
121
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
122
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
123
+ 4. Push to the branch (`git push origin my-new-feature`)
124
+ 5. Create new Pull Request
125
+
126
+ ## Credit
127
+
128
+ This gem was written and is maintained by [Jurgen Jocubeit](https://github.com/JurgenJocubeit), CEO and President Brightcommerce, Inc.
129
+
130
+ ## License
131
+
132
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
133
+
134
+ ## Copyright
135
+
136
+ Copyright 2018 Brightcommerce, Inc.
@@ -0,0 +1,3 @@
1
+ require 'active_record'
2
+ require 'attr_publish/attr_publish'
3
+ require 'attr_publish/version'
@@ -0,0 +1 @@
1
+ ActiveRecord::Base.send :include, AttrPublish
@@ -0,0 +1,226 @@
1
+ require 'active_support/concern'
2
+
3
+ module AttrPublish
4
+ extend ::ActiveSupport::Concern
5
+
6
+ class_methods do
7
+ def attr_publish(column)
8
+ return unless table_exists?
9
+
10
+ column_name = column.to_sym || :published
11
+
12
+ # Silently ignore a missing column - since bombing on a missing
13
+ # column can make re-running migrations very hard.
14
+ return unless self.columns_hash[column_name.to_s].present?
15
+
16
+ column_type = self.columns_hash[column_name.to_s].type
17
+
18
+ if respond_to?(:scope)
19
+ # Define published/unpublished scope.
20
+ case column_type
21
+ when :date
22
+ scope :published, lambda { |*args|
23
+ on_date = args[0] || Date.current
24
+ where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].lteq(on_date))
25
+ }
26
+
27
+ scope :unpublished, lambda { |*args|
28
+ on_date = args[0] || Date.current
29
+ where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].gt(on_date))
30
+ }
31
+
32
+ when :datetime
33
+ scope :published, lambda { |*args|
34
+ at_time = args[0] || Time.now
35
+ where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].lteq(at_time.utc))
36
+ }
37
+
38
+ scope :unpublished, lambda { |*args|
39
+ at_time = args[0] || Time.now
40
+ where(arel_table[column_name].not_eq(nil)).where(arel_table[column_name].gt(at_time.utc))
41
+ }
42
+
43
+ when :boolean
44
+ scope :published, lambda {
45
+ where(column_name => true)
46
+ }
47
+
48
+ scope :unpublished, lambda {
49
+ where(column_name => false)
50
+ }
51
+
52
+ else
53
+ raise ::ActiveRecord::ConfigurationError,
54
+ "Invalid column_type #{column_type} for Publishable column on model #{self.name}"
55
+ end
56
+
57
+ # Define recent/upcoming scopes.
58
+ if [:date, :datetime].include?(column_type)
59
+ scope :recent, lambda { |*args|
60
+ how_many = args[0] || nil
61
+ col_name = arel_table[column_name].name
62
+ published.limit(how_many).order("#{col_name} DESC")
63
+ }
64
+
65
+ scope :upcoming, lambda { |*args|
66
+ how_many = args[0] || nil
67
+ col_name = arel_table[column_name].name
68
+ unpublished.limit(how_many).order("#{col_name} ASC")
69
+ }
70
+ end
71
+ end
72
+
73
+ case column_type
74
+ when :datetime
75
+ class_eval <<-EVIL, __FILE__, __LINE__ + 1
76
+ def published?(_when = Time.current)
77
+ #{column_name} ? #{column_name} <= _when : false
78
+ end
79
+ def unpublished?(_when = Time.current)
80
+ !published?(_when)
81
+ end
82
+ def publish(_when = Time.current)
83
+ self.#{column_name} = _when unless published?(_when)
84
+ end
85
+ def publish!(_when = Time.current)
86
+ publish(_when) && (!respond_to?(:save) || save)
87
+ end
88
+ def unpublish()
89
+ self.#{column_name} = nil
90
+ true
91
+ end
92
+ def unpublish!()
93
+ unpublish() && (!respond_to?(:save) || save)
94
+ end
95
+ EVIL
96
+
97
+ when :date
98
+ class_eval <<-EVIL, __FILE__, __LINE__ + 1
99
+ def published?(_when = Date.current)
100
+ #{column_name} ? #{column_name} <= _when : false
101
+ end
102
+ def unpublished?(_when = Date.current)
103
+ !published?(_when)
104
+ end
105
+ def publish(_when = Date.current)
106
+ self.#{column_name} = _when unless published?(_when)
107
+ end
108
+ def publish!(_when = Date.current)
109
+ publish(_when) && (!respond_to?(:save) || save)
110
+ end
111
+ def unpublish()
112
+ self.#{column_name} = nil
113
+ end
114
+ def unpublish!()
115
+ unpublish() && (!respond_to?(:save) || save)
116
+ end
117
+ EVIL
118
+
119
+ when :boolean
120
+ class_eval <<-EVIL, __FILE__, __LINE__ + 1
121
+ def published?()
122
+ #{column_name}
123
+ end
124
+ def unpublished?()
125
+ !published?()
126
+ end
127
+ def publish()
128
+ self.#{column_name} = true
129
+ end
130
+ def publish!()
131
+ publish()
132
+ save if respond_to?(:save)
133
+ end
134
+ def unpublish()
135
+ self.#{column_name} = false
136
+ end
137
+ def unpublish!()
138
+ unpublish()
139
+ save if respond_to?(:save)
140
+ end
141
+ EVIL
142
+
143
+ else
144
+ raise ::ActiveRecord::ConfigurationError,
145
+ "Invalid column_type #{column_type} for AttrPublish column on model #{self.name}"
146
+ end
147
+ end
148
+
149
+ # @!group Query scopes added to publishable models
150
+
151
+ # @!method published
152
+ # Query scope added to publishables that can be used to find published records. For Date/DateTime publishables,
153
+ # you can pass a specific date on which the results should be published.
154
+ # @example Find only records that are currently published
155
+ # published_posts = Post.published
156
+ # @example Find only records that will be published in two days
157
+ # future_posts = Post.published(Date.current + 2.days)
158
+ # @param [Date, Time, nil] when Specify a date/time for Date/DateTime publishables - defaults to the current date/time
159
+ # @!scope class
160
+
161
+ # @!method unpublished
162
+ # Query scope added to publishables that can be used find records which are not published. For Date/DateTime
163
+ # publishables, you can pass a specific date on which the results should not have been published.
164
+ # @example Find only records that are not currently published
165
+ # unpublished_posts = Post.unpublished
166
+ # @param [Date, Time, nil] when Specify a date/time for Date/DateTime publishables - defaults to the current date/time
167
+ # @!scope class
168
+
169
+ # @!method recent
170
+ # Query scope added to publishables that can be used to lookup records which are currently published. The results
171
+ # are returned in descending order based on the published date/time.
172
+ # @example Get the 10 most recently-published records
173
+ # recent_posts = Post.recent(10)
174
+ # @param [Integer, nil] how_many Specify how many records to return
175
+ # @!scope class
176
+
177
+ # @!method upcoming
178
+ # Query scope added to publishables that can be used to lookup records which are not currently published. The
179
+ # results are returned in ascending order based on the published date/time.
180
+ # @example Get all posts that will be published in the future
181
+ # upcoming_posts = Post.upcoming
182
+ # @param [Integer, nil] how_many Specify how many records to return
183
+ # @!scope class
184
+
185
+ # @!endgroup
186
+
187
+ # @!group Instance methods added to publishable models
188
+
189
+ # @!method published?
190
+ # Is this object published?
191
+ # @param [Date, Time, nil] when For Date/DateTime publishables, a date/time can be passed to determine if the
192
+ # object was / will be published on the given date.
193
+ # @return [Boolean] true if published, false if not published.
194
+ # @!scope instance
195
+
196
+ # @!method unpublished?
197
+ # Is this object not published?
198
+ # @param [Date, Time, nil] when For Date/DateTime publishables, a date/time can be passed to determine if the
199
+ # object was not / will not be published on the given date.
200
+ # @return [Boolean] false if published, true if not published.
201
+ # @!scope instance
202
+
203
+ # @!method publish
204
+ # Publish this object. For a Boolean publish field, the field is set to true; for a Date/DateTime field, the
205
+ # field is set to the given Date/Time or to the current date/time.
206
+ # @param [Date, Time, nil] when For Date/DateTime publishables, a date/time can be passed to specify when the
207
+ # record will be published. Defaults to +Date.current+ or +Time.now+.
208
+ # @!scope instance
209
+
210
+ # @!method publish!
211
+ # Publish this object, then immediately save it to the database.
212
+ # @param [Date, Time, nil] when
213
+ # @!scope instance
214
+
215
+ # @!method unpublish
216
+ # Un-publish this object, i.e. set it to not be published. For a Boolean publish field, the field is set to
217
+ # false; for a Date/DateTime field, the field is cleared.
218
+ # @!scope instance
219
+
220
+ # @!method unpublish!
221
+ # Un-publish this object, then immediately save it to the database.
222
+ # @!scope instance
223
+
224
+ # @!endgroup
225
+ end
226
+ end
@@ -0,0 +1,16 @@
1
+ module AttrPublish
2
+ module Version
3
+ Major = 1
4
+ Minor = 0
5
+ Revision = 0
6
+ Prerelease = nil
7
+ Compact = [Major, Minor, Revision, Prerelease].compact.join('.')
8
+ Summary = "AttrPublish v#{Compact}"
9
+ Description = "ActiveRecord convenience methods and scopes for publishing and finding published, unpublished and returning recent or upcoming items."
10
+ Author = "Jurgen Jocubeit"
11
+ Email = "support@brightcommerce.com"
12
+ Homepage = "https://github.com/brightcommerce/attr_publish"
13
+ Metadata = {'copyright' => 'Copyright 2018 Brightcommerce, Inc. All Rights Reserved.'}
14
+ License = "MIT"
15
+ end
16
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attr_publish
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jurgen Jocubeit
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-12-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.1.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.1.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 5.1.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 5.1.4
41
+ description: ActiveRecord convenience methods and scopes for publishing and finding
42
+ published, unpublished and returning recent or upcoming items.
43
+ email: support@brightcommerce.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - CHANGELOG.md
49
+ - README.md
50
+ - lib/attr_publish.rb
51
+ - lib/attr_publish/active_record.rb
52
+ - lib/attr_publish/attr_publish.rb
53
+ - lib/attr_publish/version.rb
54
+ homepage: https://github.com/brightcommerce/attr_publish
55
+ licenses:
56
+ - MIT
57
+ metadata:
58
+ copyright: Copyright 2018 Brightcommerce, Inc. All Rights Reserved.
59
+ post_install_message:
60
+ rdoc_options: []
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '2.3'
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 2.6.13
76
+ signing_key:
77
+ specification_version: 4
78
+ summary: AttrPublish v1.0.0
79
+ test_files: []