unread 0.9.1 → 0.10.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.
- checksums.yaml +5 -5
- data/.travis.yml +12 -30
- data/Appraisals +5 -15
- data/MIT-LICENSE +1 -1
- data/README.md +22 -12
- data/Rakefile +1 -1
- data/UPGRADE.md +3 -3
- data/gemfiles/{rails_3_0.gemfile → rails_5_2.gemfile} +2 -2
- data/lib/unread/base.rb +4 -4
- data/lib/unread/garbage_collector.rb +5 -4
- data/lib/unread/read_mark.rb +2 -2
- data/lib/unread/readable.rb +37 -20
- data/lib/unread/reader.rb +2 -2
- data/lib/unread/version.rb +1 -1
- data/spec/app/models/document.rb +1 -1
- data/spec/support/spec_migration.rb +4 -4
- data/spec/support/timecop.rb +1 -1
- data/spec/unread/base_spec.rb +2 -2
- data/spec/unread/garbage_collector_spec.rb +5 -5
- data/spec/unread/readable_spec.rb +38 -26
- data/spec/unread/reader_spec.rb +12 -12
- data/unread.gemspec +2 -2
- metadata +9 -11
- data/gemfiles/rails_3_1.gemfile +0 -8
- data/gemfiles/rails_3_2.gemfile +0 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 783e65e652089e8325398c9f593d126f4332d83041cd2fd88cc86266105a1809
|
|
4
|
+
data.tar.gz: 24f73b4d3038e0d81acff4ca44c7fead8f628a2eea5e7479420b47952d8215fe
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ba242fd2a04f70545c5313bc73d5aff1a5bbee97b29a52625df620a3290800a90267693e8d3d5d488b00d4dd72e6dfe0a8eb1eae12428cb56ccd6cbff4dd04fe
|
|
7
|
+
data.tar.gz: 849a46af19decb7627d0359b46bfd79f269751603144e59c621d27c56caac81943b8b2ae9b85e03a0326ac84f28d4fca59288d627d4d8eacca61fe05decb1ae7
|
data/.travis.yml
CHANGED
|
@@ -1,44 +1,25 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
rvm:
|
|
3
|
-
- 2.
|
|
4
|
-
- 2.
|
|
5
|
-
- 2.
|
|
6
|
-
- 2.
|
|
7
|
-
- 2.4.1
|
|
3
|
+
- 2.2.9
|
|
4
|
+
- 2.3.6
|
|
5
|
+
- 2.4.3
|
|
6
|
+
- 2.5.0
|
|
8
7
|
gemfile:
|
|
8
|
+
- gemfiles/rails_5_2.gemfile
|
|
9
9
|
- gemfiles/rails_5_1.gemfile
|
|
10
10
|
- gemfiles/rails_5_0.gemfile
|
|
11
11
|
- gemfiles/rails_4_2.gemfile
|
|
12
12
|
- gemfiles/rails_4_1.gemfile
|
|
13
13
|
- gemfiles/rails_4_0.gemfile
|
|
14
|
-
- gemfiles/rails_3_2.gemfile
|
|
15
|
-
- gemfiles/rails_3_1.gemfile
|
|
16
|
-
- gemfiles/rails_3_0.gemfile
|
|
17
14
|
matrix:
|
|
18
15
|
exclude:
|
|
19
|
-
- rvm: 2.
|
|
20
|
-
gemfile: gemfiles/rails_5_1.gemfile
|
|
21
|
-
- rvm: 2.1.10
|
|
22
|
-
gemfile: gemfiles/rails_5_1.gemfile
|
|
23
|
-
- rvm: 2.0.0
|
|
24
|
-
gemfile: gemfiles/rails_5_0.gemfile
|
|
25
|
-
- rvm: 2.1.10
|
|
26
|
-
gemfile: gemfiles/rails_5_0.gemfile
|
|
27
|
-
- rvm: 2.3.3
|
|
28
|
-
gemfile: gemfiles/rails_3_0.gemfile
|
|
29
|
-
- rvm: 2.3.3
|
|
30
|
-
gemfile: gemfiles/rails_3_1.gemfile
|
|
31
|
-
- rvm: 2.3.3
|
|
32
|
-
gemfile: gemfiles/rails_3_2.gemfile
|
|
33
|
-
- rvm: 2.4.1
|
|
34
|
-
gemfile: gemfiles/rails_3_0.gemfile
|
|
35
|
-
- rvm: 2.4.1
|
|
36
|
-
gemfile: gemfiles/rails_3_1.gemfile
|
|
37
|
-
- rvm: 2.4.1
|
|
38
|
-
gemfile: gemfiles/rails_3_2.gemfile
|
|
39
|
-
- rvm: 2.4.1
|
|
16
|
+
- rvm: 2.4.3
|
|
40
17
|
gemfile: gemfiles/rails_4_0.gemfile
|
|
41
|
-
- rvm: 2.4.
|
|
18
|
+
- rvm: 2.4.3
|
|
19
|
+
gemfile: gemfiles/rails_4_1.gemfile
|
|
20
|
+
- rvm: 2.5.0
|
|
21
|
+
gemfile: gemfiles/rails_4_0.gemfile
|
|
22
|
+
- rvm: 2.5.0
|
|
42
23
|
gemfile: gemfiles/rails_4_1.gemfile
|
|
43
24
|
before_install: gem update bundler
|
|
44
25
|
sudo: false
|
|
@@ -47,5 +28,6 @@ env:
|
|
|
47
28
|
- DB=mysql
|
|
48
29
|
- DB=postgres
|
|
49
30
|
before_script:
|
|
31
|
+
- gem update --system # https://github.com/travis-ci/travis-ci/issues/8978
|
|
50
32
|
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS unread_test;'; fi"
|
|
51
33
|
- sh -c "if [ '$DB' = 'postgres' ]; then psql -c 'create database unread_test;' -U postgres; fi"
|
data/Appraisals
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
appraise "rails-5-2" do
|
|
2
|
+
gem "activerecord", "~> 5.2.0.beta2"
|
|
3
|
+
gem "mysql2", ">= 0.3.18", "< 0.5", "!= 0.4.3"
|
|
4
|
+
end
|
|
5
|
+
|
|
1
6
|
appraise "rails-5-1" do
|
|
2
7
|
gem "activerecord", "~> 5.1.0"
|
|
3
8
|
gem 'mysql2', '>= 0.3.18', '< 0.5'
|
|
@@ -22,18 +27,3 @@ appraise "rails-4-0" do
|
|
|
22
27
|
gem "activerecord", "~> 4.0.13"
|
|
23
28
|
gem "mysql2", '~> 0.3.10'
|
|
24
29
|
end
|
|
25
|
-
|
|
26
|
-
appraise "rails-3-2" do
|
|
27
|
-
gem "activerecord", "~> 3.2.22"
|
|
28
|
-
gem 'mysql2', '~> 0.3.10'
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
appraise "rails-3-1" do
|
|
32
|
-
gem "activerecord", "~> 3.1.12"
|
|
33
|
-
gem 'mysql2', '~> 0.3.10'
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
appraise "rails-3-0" do
|
|
37
|
-
gem "activerecord", "~> 3.0.20"
|
|
38
|
-
gem "activerecord-mysql2-adapter"
|
|
39
|
-
end
|
data/MIT-LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Unread
|
|
|
4
4
|
Ruby gem to manage read/unread status of ActiveRecord objects - and it's fast.
|
|
5
5
|
|
|
6
6
|
[](https://travis-ci.org/ledermann/unread)
|
|
7
|
-
[](https://codeclimate.com/github/ledermann/unread/maintainability)
|
|
8
8
|
[](https://coveralls.io/r/ledermann/unread?branch=master)
|
|
9
9
|
|
|
10
10
|
## Features
|
|
@@ -19,8 +19,8 @@ Ruby gem to manage read/unread status of ActiveRecord objects - and it's fast.
|
|
|
19
19
|
|
|
20
20
|
## Requirements
|
|
21
21
|
|
|
22
|
-
* Ruby 2.
|
|
23
|
-
* Rails
|
|
22
|
+
* Ruby 2.2 or newer
|
|
23
|
+
* Rails 4.0 or newer (including Rails 5.1 and 5.2)
|
|
24
24
|
* MySQL, PostgreSQL or SQLite
|
|
25
25
|
* Needs a timestamp field in your models (like created_at or updated_at) with a database index on it
|
|
26
26
|
|
|
@@ -65,12 +65,22 @@ class User < ActiveRecord::Base
|
|
|
65
65
|
|
|
66
66
|
# Optional: Allow a subset of users as readers only
|
|
67
67
|
def self.reader_scope
|
|
68
|
-
where(:
|
|
68
|
+
where(is_admin: true)
|
|
69
69
|
end
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
class Message < ActiveRecord::Base
|
|
73
|
-
acts_as_readable :
|
|
73
|
+
acts_as_readable on: :created_at
|
|
74
|
+
|
|
75
|
+
# The `on:` option sets the relevant attribute for comparing timestamps.
|
|
76
|
+
#
|
|
77
|
+
# The default is :updated_at, so updating a record, which was read by a
|
|
78
|
+
# reader makes it unread again.
|
|
79
|
+
#
|
|
80
|
+
# Using :created_at, only new records will show up as unread. Updating a
|
|
81
|
+
# record which was read by a reader, will NOT mark it as unread.
|
|
82
|
+
#
|
|
83
|
+
# Any other existing timestamp field can be used as `on:` option.
|
|
74
84
|
end
|
|
75
85
|
|
|
76
86
|
message1 = Message.create!
|
|
@@ -80,7 +90,7 @@ message2 = Message.create!
|
|
|
80
90
|
Message.unread_by(current_user)
|
|
81
91
|
# => [ message1, message2 ]
|
|
82
92
|
|
|
83
|
-
message1.mark_as_read! :
|
|
93
|
+
message1.mark_as_read! for: current_user
|
|
84
94
|
Message.unread_by(current_user)
|
|
85
95
|
# => [ message2 ]
|
|
86
96
|
|
|
@@ -88,7 +98,7 @@ Message.unread_by(current_user)
|
|
|
88
98
|
Message.read_by(current_user)
|
|
89
99
|
# => [ ]
|
|
90
100
|
|
|
91
|
-
message1.mark_as_read! :
|
|
101
|
+
message1.mark_as_read! for: current_user
|
|
92
102
|
Message.read_by(current_user)
|
|
93
103
|
# => [ message1 ]
|
|
94
104
|
|
|
@@ -100,7 +110,7 @@ messages[0].unread?(current_user)
|
|
|
100
110
|
messages[1].unread?(current_user)
|
|
101
111
|
# => true
|
|
102
112
|
|
|
103
|
-
Message.mark_as_read! :all, :
|
|
113
|
+
Message.mark_as_read! :all, for: current_user
|
|
104
114
|
Message.unread_by(current_user)
|
|
105
115
|
# => [ ]
|
|
106
116
|
|
|
@@ -114,7 +124,7 @@ user2 = User.create!
|
|
|
114
124
|
User.have_not_read(message1)
|
|
115
125
|
# => [ user1, user2 ]
|
|
116
126
|
|
|
117
|
-
message1.mark_as_read! :
|
|
127
|
+
message1.mark_as_read! for: user1
|
|
118
128
|
User.have_not_read(message1)
|
|
119
129
|
# => [ user2 ]
|
|
120
130
|
|
|
@@ -122,11 +132,11 @@ User.have_not_read(message1)
|
|
|
122
132
|
User.have_read(message1)
|
|
123
133
|
# => [ user1 ]
|
|
124
134
|
|
|
125
|
-
message1.mark_as_read! :
|
|
135
|
+
message1.mark_as_read! for: user2
|
|
126
136
|
User.have_read(message1)
|
|
127
137
|
# => [ user1, user2 ]
|
|
128
138
|
|
|
129
|
-
Message.mark_as_read! :all, :
|
|
139
|
+
Message.mark_as_read! :all, for: user1
|
|
130
140
|
User.have_not_read(message1)
|
|
131
141
|
# => [ ]
|
|
132
142
|
User.have_not_read(message2)
|
|
@@ -189,4 +199,4 @@ AND messages.created_at > '2010-10-20 08:50:00'
|
|
|
189
199
|
Hint: You should add a database index on `messages.created_at`.
|
|
190
200
|
|
|
191
201
|
|
|
192
|
-
Copyright (c) 2010-
|
|
202
|
+
Copyright (c) 2010-2018 [Georg Ledermann](http://www.georg-ledermann.de) and [contributors](https://github.com/ledermann/unread/graphs/contributors), released under the MIT license
|
data/Rakefile
CHANGED
data/UPGRADE.md
CHANGED
|
@@ -11,7 +11,7 @@ The gem accepts any type of classes as reader and it's not limited to `User` cla
|
|
|
11
11
|
|
|
12
12
|
```ruby
|
|
13
13
|
Customer.have_not_read(message1)
|
|
14
|
-
message1.mark_as_read! :
|
|
14
|
+
message1.mark_as_read! for: Customer.find(1)
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
If you are upgrading from v0.6.3 or older, you need to do the following after upgrading:
|
|
@@ -32,7 +32,7 @@ The class method `acts_as_reader` doesn't take the option `:scope` anymore. If y
|
|
|
32
32
|
|
|
33
33
|
```ruby
|
|
34
34
|
class User < ActiveRecord::Base
|
|
35
|
-
acts_as_reader :
|
|
35
|
+
acts_as_reader scope: -> { where(is_admin: true) }
|
|
36
36
|
end
|
|
37
37
|
```
|
|
38
38
|
|
|
@@ -43,7 +43,7 @@ class User < ActiveRecord::Base
|
|
|
43
43
|
acts_as_reader
|
|
44
44
|
|
|
45
45
|
def self.reader_scope
|
|
46
|
-
where(:
|
|
46
|
+
where(is_admin: true)
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
```
|
data/lib/unread/base.rb
CHANGED
|
@@ -8,9 +8,9 @@ module Unread
|
|
|
8
8
|
ReadMark.reader_classes ||= []
|
|
9
9
|
|
|
10
10
|
unless ReadMark.reader_classes.include?(self)
|
|
11
|
-
ReadMark.belongs_to :reader, :
|
|
11
|
+
ReadMark.belongs_to :reader, polymorphic: true, inverse_of: :read_marks
|
|
12
12
|
|
|
13
|
-
has_many :read_marks, :
|
|
13
|
+
has_many :read_marks, dependent: :delete_all, as: :reader, inverse_of: :reader
|
|
14
14
|
|
|
15
15
|
after_create :setup_new_reader
|
|
16
16
|
|
|
@@ -28,10 +28,10 @@ module Unread
|
|
|
28
28
|
unless ReadMark.readable_classes.include?(self)
|
|
29
29
|
class_attribute :readable_options
|
|
30
30
|
|
|
31
|
-
options.reverse_merge!(:
|
|
31
|
+
options.reverse_merge!(on: :updated_at)
|
|
32
32
|
self.readable_options = options
|
|
33
33
|
|
|
34
|
-
has_many :read_marks, :
|
|
34
|
+
has_many :read_marks, as: :readable, dependent: :delete_all, inverse_of: :readable
|
|
35
35
|
|
|
36
36
|
ReadMark.readable_classes << self
|
|
37
37
|
|
|
@@ -7,7 +7,7 @@ module Unread
|
|
|
7
7
|
|
|
8
8
|
def run!
|
|
9
9
|
ReadMark.reader_classes.each do |reader_class|
|
|
10
|
-
readers_to_cleanup(reader_class).
|
|
10
|
+
readers_to_cleanup(reader_class).find_each do |reader|
|
|
11
11
|
if oldest_timestamp = readable_class.read_scope(reader).
|
|
12
12
|
unread_by(reader).
|
|
13
13
|
minimum(readable_class.readable_options[:on])
|
|
@@ -29,16 +29,17 @@ module Unread
|
|
|
29
29
|
reader_class.
|
|
30
30
|
reader_scope.
|
|
31
31
|
joins(:read_marks).
|
|
32
|
-
where(ReadMark.table_name => { :
|
|
32
|
+
where(ReadMark.table_name => { readable_type: readable_class.name }).
|
|
33
33
|
group("#{ReadMark.quoted_table_name}.reader_type, #{ReadMark.quoted_table_name}.reader_id, #{reader_class.quoted_table_name}.#{reader_class.quoted_primary_key}").
|
|
34
|
-
having("COUNT(#{ReadMark.quoted_table_name}.id) > 1")
|
|
34
|
+
having("COUNT(#{ReadMark.quoted_table_name}.id) > 1").
|
|
35
|
+
select("#{reader_class.quoted_table_name}.#{reader_class.quoted_primary_key}")
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def update_read_marks_for_user(reader, timestamp)
|
|
38
39
|
ReadMark.transaction do
|
|
39
40
|
# Delete markers OLDER than the given timestamp
|
|
40
41
|
reader.read_marks.
|
|
41
|
-
where(:
|
|
42
|
+
where(readable_type: readable_class.name).
|
|
42
43
|
single.
|
|
43
44
|
older_than(timestamp).
|
|
44
45
|
delete_all
|
data/lib/unread/read_mark.rb
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
class ReadMark < ActiveRecord::Base
|
|
2
|
-
belongs_to :readable, :
|
|
2
|
+
belongs_to :readable, polymorphic: true, inverse_of: :read_marks
|
|
3
3
|
|
|
4
4
|
validates_presence_of :reader_id, :reader_type, :readable_type
|
|
5
5
|
|
|
6
|
-
scope :global, lambda { where(:
|
|
6
|
+
scope :global, lambda { where(readable_id: nil) }
|
|
7
7
|
scope :single, lambda { where('readable_id IS NOT NULL') }
|
|
8
8
|
scope :older_than, lambda { |timestamp| where([ 'timestamp < ?', timestamp ]) }
|
|
9
9
|
|
data/lib/unread/readable.rb
CHANGED
|
@@ -9,41 +9,58 @@ module Unread
|
|
|
9
9
|
|
|
10
10
|
if target == :all
|
|
11
11
|
reset_read_marks_for_user(reader)
|
|
12
|
-
elsif target.
|
|
13
|
-
|
|
12
|
+
elsif target.respond_to?(:each)
|
|
13
|
+
mark_collection_as_read(target, reader)
|
|
14
14
|
else
|
|
15
15
|
raise ArgumentError
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def
|
|
19
|
+
def mark_collection_as_read(collection, reader)
|
|
20
20
|
ReadMark.transaction do
|
|
21
21
|
global_timestamp = reader.read_mark_global(self).try(:timestamp)
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
collection.each do |obj|
|
|
24
24
|
raise ArgumentError unless obj.is_a?(self)
|
|
25
25
|
timestamp = obj.send(readable_options[:on])
|
|
26
26
|
|
|
27
27
|
if global_timestamp && global_timestamp >= timestamp
|
|
28
28
|
# The object is implicitly marked as read, so there is nothing to do
|
|
29
29
|
else
|
|
30
|
-
|
|
31
|
-
ReadMark.transaction(requires_new: true) do
|
|
32
|
-
begin
|
|
33
|
-
rm = obj.read_marks.where(reader_id: reader.id, reader_type: reader.class.base_class.name).first || obj.read_marks.build
|
|
34
|
-
rm.reader_id = reader.id
|
|
35
|
-
rm.reader_type = reader.class.base_class.name
|
|
36
|
-
rm.timestamp = timestamp
|
|
37
|
-
rm.save!
|
|
38
|
-
rescue ActiveRecord::RecordNotUnique
|
|
39
|
-
raise ActiveRecord::Rollback
|
|
40
|
-
end
|
|
41
|
-
end
|
|
30
|
+
mark_collection_item_as_read(obj, reader, timestamp)
|
|
42
31
|
end
|
|
43
32
|
end
|
|
44
33
|
end
|
|
45
34
|
end
|
|
46
35
|
|
|
36
|
+
def mark_collection_item_as_read(obj, reader, timestamp)
|
|
37
|
+
marking_proc = proc {
|
|
38
|
+
rm = obj.read_marks.find_or_initialize_by(reader: reader)
|
|
39
|
+
rm.timestamp = timestamp
|
|
40
|
+
rm.save!
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if using_postgresql?
|
|
44
|
+
# With PostgreSQL, a transaction is unusable after a unique constraint vialoation.
|
|
45
|
+
# To avoid this, nested transactions are required.
|
|
46
|
+
# http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Exception+handling+and+rolling+back
|
|
47
|
+
ReadMark.transaction(requires_new: true) do
|
|
48
|
+
begin
|
|
49
|
+
marking_proc.call
|
|
50
|
+
rescue ActiveRecord::RecordNotUnique
|
|
51
|
+
# The object is explicitly marked as read, so rollback the inner transaction
|
|
52
|
+
raise ActiveRecord::Rollback
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
else
|
|
56
|
+
begin
|
|
57
|
+
marking_proc.call
|
|
58
|
+
rescue ActiveRecord::RecordNotUnique
|
|
59
|
+
# The object is explicitly marked as read, so there is nothing to do
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
47
64
|
# A scope with all items accessable for the given reader
|
|
48
65
|
# It's used in cleanup_read_marks! to support a filtered cleanup
|
|
49
66
|
# Should be overriden if a reader doesn't have access to all items
|
|
@@ -70,7 +87,7 @@ module Unread
|
|
|
70
87
|
assert_reader(reader)
|
|
71
88
|
|
|
72
89
|
ReadMark.transaction do
|
|
73
|
-
reader.read_marks.where(:
|
|
90
|
+
reader.read_marks.where(readable_type: self.readable_parent.name).delete_all
|
|
74
91
|
rm = reader.read_marks.new
|
|
75
92
|
rm.readable_type = self.readable_parent.name
|
|
76
93
|
rm.timestamp = Time.current
|
|
@@ -123,12 +140,12 @@ module Unread
|
|
|
123
140
|
end
|
|
124
141
|
end
|
|
125
142
|
|
|
143
|
+
private
|
|
144
|
+
|
|
126
145
|
def read_mark(reader)
|
|
127
|
-
read_marks.where(:
|
|
146
|
+
read_marks.where(reader_id: reader.id, reader_type: reader.class.base_class.name).first
|
|
128
147
|
end
|
|
129
148
|
|
|
130
|
-
private
|
|
131
|
-
|
|
132
149
|
def read_mark_id_belongs_to?(reader)
|
|
133
150
|
self.read_mark_reader_id.to_i == reader.id &&
|
|
134
151
|
self.read_mark_reader_type == reader.class.base_class.name
|
data/lib/unread/reader.rb
CHANGED
|
@@ -16,7 +16,7 @@ module Unread
|
|
|
16
16
|
def read_mark_global(klass)
|
|
17
17
|
@read_mark_global ||= {}
|
|
18
18
|
readable_klass = klass.readable_parent
|
|
19
|
-
@read_mark_global[readable_klass] ||= read_marks.where(:
|
|
19
|
+
@read_mark_global[readable_klass] ||= read_marks.where(readable_type: readable_klass.name).global.first
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
def forget_memoized_read_mark_global
|
|
@@ -44,7 +44,7 @@ module Unread
|
|
|
44
44
|
# If you don't want this, you can override this method in your reader class
|
|
45
45
|
def setup_new_reader
|
|
46
46
|
(ReadMark.readable_classes || []).each do |klass|
|
|
47
|
-
klass.mark_as_read! :all, :
|
|
47
|
+
klass.mark_as_read! :all, for: self
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
end
|
data/lib/unread/version.rb
CHANGED
data/spec/app/models/document.rb
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
class SpecMigration < Unread::MIGRATION_BASE_CLASS
|
|
2
2
|
def self.up
|
|
3
|
-
create_table Reader, :
|
|
3
|
+
create_table Reader, primary_key: 'number', force: true do |t|
|
|
4
4
|
t.string :name
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
create_table DifferentReader, :
|
|
7
|
+
create_table DifferentReader, primary_key: 'number', force: true do |t|
|
|
8
8
|
t.string :name
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
create_table Customer, :
|
|
11
|
+
create_table Customer, force: true do |t|
|
|
12
12
|
t.string :type
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
create_table Document, :
|
|
15
|
+
create_table Document, primary_key: 'uid', force: true do |t|
|
|
16
16
|
t.string :type
|
|
17
17
|
t.string :subject
|
|
18
18
|
t.text :content
|
data/spec/support/timecop.rb
CHANGED
data/spec/unread/base_spec.rb
CHANGED
|
@@ -4,7 +4,7 @@ describe Unread::Base do
|
|
|
4
4
|
before :each do
|
|
5
5
|
@email = Email.create!
|
|
6
6
|
wait
|
|
7
|
-
@reader = Reader.create! :
|
|
7
|
+
@reader = Reader.create! name: 'John'
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
describe :acts_as_reader do
|
|
@@ -47,7 +47,7 @@ describe Unread::Base do
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
it "should use default options" do
|
|
50
|
-
expect(Email.readable_options).to eq({ :
|
|
50
|
+
expect(Email.readable_options).to eq({ on: :updated_at })
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it "should be idempotent" do
|
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Unread::GarbageCollector do
|
|
4
4
|
before :each do
|
|
5
|
-
@reader = Reader.create! :
|
|
6
|
-
@other_reader = Reader.create :
|
|
5
|
+
@reader = Reader.create! name: 'David'
|
|
6
|
+
@other_reader = Reader.create name: 'Matz'
|
|
7
7
|
@sti_reader = StiReader.create!
|
|
8
8
|
wait
|
|
9
9
|
@email1 = Email.create!
|
|
@@ -15,7 +15,7 @@ describe Unread::GarbageCollector do
|
|
|
15
15
|
it "should delete all single read marks" do
|
|
16
16
|
expect(@reader.read_marks.single.count).to eq 0
|
|
17
17
|
|
|
18
|
-
@email1.mark_as_read! :
|
|
18
|
+
@email1.mark_as_read! for: @reader
|
|
19
19
|
|
|
20
20
|
expect(Email.unread_by(@reader)).to eq [@email2]
|
|
21
21
|
expect(@reader.read_marks.single.count).to eq 1
|
|
@@ -27,8 +27,8 @@ describe Unread::GarbageCollector do
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "should reset if all objects are read" do
|
|
30
|
-
@email1.mark_as_read! :
|
|
31
|
-
@email2.mark_as_read! :
|
|
30
|
+
@email1.mark_as_read! for: @reader
|
|
31
|
+
@email2.mark_as_read! for: @reader
|
|
32
32
|
|
|
33
33
|
expect(@reader.read_marks.single.count).to eq 2
|
|
34
34
|
|
|
@@ -2,8 +2,8 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Unread::Readable do
|
|
4
4
|
before :each do
|
|
5
|
-
@reader = Reader.create! :
|
|
6
|
-
@other_reader = Reader.create :
|
|
5
|
+
@reader = Reader.create! name: 'David'
|
|
6
|
+
@other_reader = Reader.create name: 'Matz'
|
|
7
7
|
@sti_reader = StiReader.create!
|
|
8
8
|
wait
|
|
9
9
|
@email1 = Email.create!
|
|
@@ -18,7 +18,7 @@ describe Unread::Readable do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "should return unread records" do
|
|
21
|
-
@email1.mark_as_read! :
|
|
21
|
+
@email1.mark_as_read! for: @reader
|
|
22
22
|
|
|
23
23
|
expect(Email.unread_by(@reader)).to eq [@email2]
|
|
24
24
|
expect(Email.unread_by(@reader).count).to eq 1
|
|
@@ -27,7 +27,7 @@ describe Unread::Readable do
|
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
it "should return empty array directly after marking all as read" do
|
|
30
|
-
Email.mark_as_read! :all, :
|
|
30
|
+
Email.mark_as_read! :all, for: @reader
|
|
31
31
|
expect(Email.unread_by(@reader)).to eq([])
|
|
32
32
|
end
|
|
33
33
|
|
|
@@ -58,7 +58,7 @@ describe Unread::Readable do
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
it "should return unread records" do
|
|
61
|
-
@email1.mark_as_read! :
|
|
61
|
+
@email1.mark_as_read! for: @reader
|
|
62
62
|
|
|
63
63
|
expect(Email.unread_by(@reader)).to eq [@email2]
|
|
64
64
|
expect(Email.unread_by(@reader).count).to eq 1
|
|
@@ -89,14 +89,14 @@ describe Unread::Readable do
|
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
it "should return read records" do
|
|
92
|
-
@email1.mark_as_read! :
|
|
92
|
+
@email1.mark_as_read! for: @reader
|
|
93
93
|
|
|
94
94
|
expect(Email.read_by(@reader)).to eq [@email1]
|
|
95
95
|
expect(Email.read_by(@reader).count).to eq 1
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
it "should return all records when all read" do
|
|
99
|
-
Email.mark_as_read! :all, :
|
|
99
|
+
Email.mark_as_read! :all, for: @reader
|
|
100
100
|
|
|
101
101
|
expect(Email.read_by(@reader)).to eq [@email1, @email2]
|
|
102
102
|
end
|
|
@@ -128,14 +128,14 @@ describe Unread::Readable do
|
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
it "should return read records" do
|
|
131
|
-
@email1.mark_as_read! :
|
|
131
|
+
@email1.mark_as_read! for: @reader
|
|
132
132
|
|
|
133
133
|
expect(Email.read_by(@reader)).to eq [@email1]
|
|
134
134
|
expect(Email.read_by(@reader).count).to eq 1
|
|
135
135
|
end
|
|
136
136
|
|
|
137
137
|
it "should return all records when all read" do
|
|
138
|
-
Email.mark_as_read! :all, :
|
|
138
|
+
Email.mark_as_read! :all, for: @reader
|
|
139
139
|
|
|
140
140
|
expect(Email.read_by(@reader)).to eq [@email1, @email2]
|
|
141
141
|
end
|
|
@@ -191,11 +191,11 @@ describe Unread::Readable do
|
|
|
191
191
|
end
|
|
192
192
|
|
|
193
193
|
it "should handle updating object" do
|
|
194
|
-
@email1.mark_as_read! :
|
|
194
|
+
@email1.mark_as_read! for: @reader
|
|
195
195
|
wait
|
|
196
196
|
expect(@email1.unread?(@reader)).to be_falsey
|
|
197
197
|
|
|
198
|
-
@email1.update_attributes! :
|
|
198
|
+
@email1.update_attributes! subject: 'changed'
|
|
199
199
|
expect(@email1.unread?(@reader)).to be_truthy
|
|
200
200
|
end
|
|
201
201
|
|
|
@@ -206,7 +206,7 @@ describe Unread::Readable do
|
|
|
206
206
|
end
|
|
207
207
|
|
|
208
208
|
it "should work with eager-loaded read marks" do
|
|
209
|
-
@email1.mark_as_read! :
|
|
209
|
+
@email1.mark_as_read! for: @reader
|
|
210
210
|
|
|
211
211
|
expect {
|
|
212
212
|
emails = Email.with_read_marks_for(@reader).to_a
|
|
@@ -225,7 +225,7 @@ describe Unread::Readable do
|
|
|
225
225
|
end
|
|
226
226
|
|
|
227
227
|
it "should work with eager-loaded read marks for the correct reader" do
|
|
228
|
-
@email1.mark_as_read! :
|
|
228
|
+
@email1.mark_as_read! for: @reader
|
|
229
229
|
|
|
230
230
|
emails = Email.with_read_marks_for(@reader).to_a
|
|
231
231
|
expect(emails[0].unread?(@reader)).to be_falsey
|
|
@@ -235,7 +235,7 @@ describe Unread::Readable do
|
|
|
235
235
|
|
|
236
236
|
describe '#mark_as_read!' do
|
|
237
237
|
it "should mark a single object as read" do
|
|
238
|
-
@email1.mark_as_read! :
|
|
238
|
+
@email1.mark_as_read! for: @reader
|
|
239
239
|
|
|
240
240
|
expect(@email1.unread?(@reader)).to be_falsey
|
|
241
241
|
expect(Email.unread_by(@reader)).to eq [@email2]
|
|
@@ -248,8 +248,8 @@ describe Unread::Readable do
|
|
|
248
248
|
end
|
|
249
249
|
|
|
250
250
|
it "should be idempotent" do
|
|
251
|
-
@email1.mark_as_read! :
|
|
252
|
-
@email1.mark_as_read! :
|
|
251
|
+
@email1.mark_as_read! for: @reader
|
|
252
|
+
@email1.mark_as_read! for: @reader
|
|
253
253
|
|
|
254
254
|
expect(@reader.read_marks.single.count).to eq 1
|
|
255
255
|
end
|
|
@@ -260,7 +260,7 @@ describe Unread::Readable do
|
|
|
260
260
|
expect(@email1.unread?(@reader)).to be_truthy
|
|
261
261
|
expect(@email2.unread?(@reader)).to be_truthy
|
|
262
262
|
|
|
263
|
-
Email.mark_as_read! [ @email1, @email2 ], :
|
|
263
|
+
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
|
264
264
|
|
|
265
265
|
expect(@email1.unread?(@reader)).to be_falsey
|
|
266
266
|
expect(@email2.unread?(@reader)).to be_falsey
|
|
@@ -269,8 +269,8 @@ describe Unread::Readable do
|
|
|
269
269
|
it "should mark the rest as read when the first record is not unique" do
|
|
270
270
|
Email.mark_as_read! [ @email1 ], for: @reader
|
|
271
271
|
|
|
272
|
-
allow(@email1).to receive_message_chain("read_marks.
|
|
273
|
-
|
|
272
|
+
allow(@email1).to receive_message_chain("read_marks.find_or_initialize_by")
|
|
273
|
+
.and_return(@email1.read_marks.build(reader: @reader))
|
|
274
274
|
|
|
275
275
|
expect do
|
|
276
276
|
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
|
@@ -281,15 +281,22 @@ describe Unread::Readable do
|
|
|
281
281
|
end
|
|
282
282
|
|
|
283
283
|
it "should perform less queries if the objects are already read" do
|
|
284
|
-
Email.mark_as_read! :all, :
|
|
284
|
+
Email.mark_as_read! :all, for: @reader
|
|
285
285
|
|
|
286
286
|
expect {
|
|
287
|
-
Email.mark_as_read! [ @email1, @email2 ], :
|
|
287
|
+
Email.mark_as_read! [ @email1, @email2 ], for: @reader
|
|
288
288
|
}.to perform_queries(1)
|
|
289
289
|
end
|
|
290
290
|
|
|
291
|
+
it "should allow a collection of records to be marked as read" do
|
|
292
|
+
Email.mark_as_read! Email.all, for: @reader
|
|
293
|
+
|
|
294
|
+
expect(@email1.unread?(@reader)).to be_falsey
|
|
295
|
+
expect(@email2.unread?(@reader)).to be_falsey
|
|
296
|
+
end
|
|
297
|
+
|
|
291
298
|
it "should mark all objects as read" do
|
|
292
|
-
Email.mark_as_read! :all, :
|
|
299
|
+
Email.mark_as_read! :all, for: @reader
|
|
293
300
|
|
|
294
301
|
expect(@reader.read_mark_global(Email).timestamp).to eq Time.current
|
|
295
302
|
expect(@reader.read_marks.single).to eq []
|
|
@@ -300,8 +307,8 @@ describe Unread::Readable do
|
|
|
300
307
|
it "should mark all objects as read with existing read objects" do
|
|
301
308
|
wait
|
|
302
309
|
|
|
303
|
-
Email.mark_as_read! :all, :
|
|
304
|
-
@email1.mark_as_read! :
|
|
310
|
+
Email.mark_as_read! :all, for: @reader
|
|
311
|
+
@email1.mark_as_read! for: @reader
|
|
305
312
|
|
|
306
313
|
expect(@reader.read_marks.single).to eq []
|
|
307
314
|
end
|
|
@@ -309,19 +316,24 @@ describe Unread::Readable do
|
|
|
309
316
|
it "should reset memoized global read mark" do
|
|
310
317
|
rm_global = @reader.read_mark_global(Email)
|
|
311
318
|
|
|
312
|
-
Email.mark_as_read! :all, :
|
|
319
|
+
Email.mark_as_read! :all, for: @reader
|
|
313
320
|
expect(@reader.read_mark_global(Email)).not_to eq(rm_global)
|
|
314
321
|
end
|
|
315
322
|
|
|
316
323
|
it "should not allow invalid arguments" do
|
|
317
324
|
expect {
|
|
318
|
-
Email.mark_as_read! :foo, :
|
|
325
|
+
Email.mark_as_read! :foo, for: @reader
|
|
319
326
|
}.to raise_error(ArgumentError)
|
|
320
327
|
|
|
321
328
|
expect {
|
|
322
329
|
Email.mark_as_read! :foo, :bar
|
|
323
330
|
}.to raise_error(ArgumentError)
|
|
324
331
|
end
|
|
332
|
+
|
|
333
|
+
it "should work with STI readers" do
|
|
334
|
+
Email.mark_as_read! [ @email1 ], for: Customer.find(@sti_reader.id)
|
|
335
|
+
expect(@email1.unread?(@sti_reader)).to be_falsey
|
|
336
|
+
end
|
|
325
337
|
end
|
|
326
338
|
|
|
327
339
|
describe :cleanup_read_marks! do
|
data/spec/unread/reader_spec.rb
CHANGED
|
@@ -2,9 +2,9 @@ require 'spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Unread::Reader do
|
|
4
4
|
before :each do
|
|
5
|
-
@reader = Reader.create! :
|
|
6
|
-
@other_reader = Reader.create :
|
|
7
|
-
@different_reader = DifferentReader.create! :
|
|
5
|
+
@reader = Reader.create! name: 'David'
|
|
6
|
+
@other_reader = Reader.create name: 'Matz'
|
|
7
|
+
@different_reader = DifferentReader.create! name: 'Behrooz', number: @reader.number
|
|
8
8
|
wait
|
|
9
9
|
@email1 = Email.create!
|
|
10
10
|
wait
|
|
@@ -18,7 +18,7 @@ describe Unread::Reader do
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "should return *only* the readers that have not read a given object" do
|
|
21
|
-
@email1.mark_as_read! :
|
|
21
|
+
@email1.mark_as_read! for: @reader
|
|
22
22
|
|
|
23
23
|
expect(Reader.have_not_read(@email1)).to eq [@other_reader]
|
|
24
24
|
expect(Reader.have_not_read(@email1).count).to eq 1
|
|
@@ -30,7 +30,7 @@ describe Unread::Reader do
|
|
|
30
30
|
# even though the id of @reader and @different_reader is the same because
|
|
31
31
|
# they are different object types, the @email1 should only be marked as
|
|
32
32
|
# read for @reader.
|
|
33
|
-
@email1.mark_as_read! :
|
|
33
|
+
@email1.mark_as_read! for: @reader
|
|
34
34
|
|
|
35
35
|
expect(Reader.have_not_read(@email1)).to eq [@other_reader]
|
|
36
36
|
expect(Reader.have_not_read(@email1).count).to eq 1
|
|
@@ -38,7 +38,7 @@ describe Unread::Reader do
|
|
|
38
38
|
expect(DifferentReader.have_not_read(@email1)).to eq [@different_reader]
|
|
39
39
|
expect(DifferentReader.have_not_read(@email1).count).to eq 1
|
|
40
40
|
|
|
41
|
-
@email1.mark_as_read! :
|
|
41
|
+
@email1.mark_as_read! for: @different_reader
|
|
42
42
|
|
|
43
43
|
expect(DifferentReader.have_not_read(@email1).count).to eq 0
|
|
44
44
|
|
|
@@ -69,7 +69,7 @@ describe Unread::Reader do
|
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it "should return *only* the readers that have read the given object" do
|
|
72
|
-
@email1.mark_as_read! :
|
|
72
|
+
@email1.mark_as_read! for: @reader
|
|
73
73
|
|
|
74
74
|
expect(Reader.have_read(@email1)).to eq [@reader]
|
|
75
75
|
expect(Reader.have_read(@email1).count).to eq 1
|
|
@@ -78,7 +78,7 @@ describe Unread::Reader do
|
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
it "should return the reader for all the object when all read" do
|
|
81
|
-
Email.mark_as_read! :all, :
|
|
81
|
+
Email.mark_as_read! :all, for: @reader
|
|
82
82
|
|
|
83
83
|
expect(Reader.have_read(@email1)).to eq [@reader]
|
|
84
84
|
expect(Reader.have_read(@email1).count).to eq 1
|
|
@@ -145,11 +145,11 @@ describe Unread::Reader do
|
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
it "should handle updating object" do
|
|
148
|
-
@email1.mark_as_read! :
|
|
148
|
+
@email1.mark_as_read! for: @reader
|
|
149
149
|
wait
|
|
150
150
|
expect(@reader.have_read?(@email1)).to be_truthy
|
|
151
151
|
|
|
152
|
-
@email1.update_attributes! :
|
|
152
|
+
@email1.update_attributes! subject: 'changed'
|
|
153
153
|
expect(@reader.have_read?(@email1)).to be_falsey
|
|
154
154
|
end
|
|
155
155
|
|
|
@@ -160,7 +160,7 @@ describe Unread::Reader do
|
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
it "should work with eager-loaded read marks" do
|
|
163
|
-
@email1.mark_as_read! :
|
|
163
|
+
@email1.mark_as_read! for: @reader
|
|
164
164
|
|
|
165
165
|
expect {
|
|
166
166
|
readers = Reader.with_read_marks_for(@email1).to_a
|
|
@@ -171,7 +171,7 @@ describe Unread::Reader do
|
|
|
171
171
|
end
|
|
172
172
|
|
|
173
173
|
it "should work with eager-loaded read marks for the correct readable" do
|
|
174
|
-
@email1.mark_as_read! :
|
|
174
|
+
@email1.mark_as_read! for: @reader
|
|
175
175
|
|
|
176
176
|
readers = Reader.with_read_marks_for(@email1).to_a
|
|
177
177
|
expect(readers[0].have_read?(@email1)).to be_truthy
|
data/unread.gemspec
CHANGED
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
|
|
|
11
11
|
s.homepage = "https://github.com/ledermann/unread"
|
|
12
12
|
s.summary = %q{Manages read/unread status of ActiveRecord objects}
|
|
13
13
|
s.description = %q{This gem creates a scope for unread objects and adds methods to mark objects as read }
|
|
14
|
-
s.required_ruby_version = '>= 2.
|
|
14
|
+
s.required_ruby_version = '>= 2.2'
|
|
15
15
|
|
|
16
16
|
s.rubyforge_project = "unread"
|
|
17
17
|
|
|
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
|
|
|
26
26
|
s.add_development_dependency 'timecop'
|
|
27
27
|
s.add_development_dependency 'sqlite3'
|
|
28
28
|
s.add_development_dependency 'mysql2'
|
|
29
|
-
s.add_development_dependency 'pg'
|
|
29
|
+
s.add_development_dependency 'pg', '< 1'
|
|
30
30
|
s.add_development_dependency 'rspec'
|
|
31
31
|
s.add_development_dependency 'simplecov'
|
|
32
32
|
s.add_development_dependency 'term-ansicolor'
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: unread
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Georg Ledermann
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2018-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activerecord
|
|
@@ -84,16 +84,16 @@ dependencies:
|
|
|
84
84
|
name: pg
|
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
|
86
86
|
requirements:
|
|
87
|
-
- - "
|
|
87
|
+
- - "<"
|
|
88
88
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: '
|
|
89
|
+
version: '1'
|
|
90
90
|
type: :development
|
|
91
91
|
prerelease: false
|
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
93
|
requirements:
|
|
94
|
-
- - "
|
|
94
|
+
- - "<"
|
|
95
95
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: '
|
|
96
|
+
version: '1'
|
|
97
97
|
- !ruby/object:Gem::Dependency
|
|
98
98
|
name: rspec
|
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -182,14 +182,12 @@ files:
|
|
|
182
182
|
- Rakefile
|
|
183
183
|
- UPGRADE.md
|
|
184
184
|
- bin/console
|
|
185
|
-
- gemfiles/rails_3_0.gemfile
|
|
186
|
-
- gemfiles/rails_3_1.gemfile
|
|
187
|
-
- gemfiles/rails_3_2.gemfile
|
|
188
185
|
- gemfiles/rails_4_0.gemfile
|
|
189
186
|
- gemfiles/rails_4_1.gemfile
|
|
190
187
|
- gemfiles/rails_4_2.gemfile
|
|
191
188
|
- gemfiles/rails_5_0.gemfile
|
|
192
189
|
- gemfiles/rails_5_1.gemfile
|
|
190
|
+
- gemfiles/rails_5_2.gemfile
|
|
193
191
|
- lib/generators/unread/migration/migration_generator.rb
|
|
194
192
|
- lib/generators/unread/migration/templates/migration.rb
|
|
195
193
|
- lib/generators/unread/polymorphic_reader_migration/polymorphic_reader_migration_generator.rb
|
|
@@ -235,7 +233,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
235
233
|
requirements:
|
|
236
234
|
- - ">="
|
|
237
235
|
- !ruby/object:Gem::Version
|
|
238
|
-
version: 2.
|
|
236
|
+
version: '2.2'
|
|
239
237
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
240
238
|
requirements:
|
|
241
239
|
- - ">="
|
|
@@ -243,7 +241,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
243
241
|
version: '0'
|
|
244
242
|
requirements: []
|
|
245
243
|
rubyforge_project: unread
|
|
246
|
-
rubygems_version: 2.
|
|
244
|
+
rubygems_version: 2.7.5
|
|
247
245
|
signing_key:
|
|
248
246
|
specification_version: 4
|
|
249
247
|
summary: Manages read/unread status of ActiveRecord objects
|
data/gemfiles/rails_3_1.gemfile
DELETED