acts_as_readable 2.2.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2eb3570785a65d3e80567534270dae5825eceb07fdeec498764c2065f129892
4
- data.tar.gz: c9bacbe67acb169365404c423640fd4f25d9536315228d014bea8c6e7e100987
3
+ metadata.gz: 26f1b10303846fe0f6adb4dd943ca37ba592463bfaf57b6dbf8f55008bca9d9f
4
+ data.tar.gz: c108f52d20a6b6e32f76b57486a87dffcea367b33e2b9d11845761cbde28bb76
5
5
  SHA512:
6
- metadata.gz: c7ddc495d6010d7748b134c731908c1a2e71b88b4cc86b8f694729e4bc1c83659e10bf0b0547801012124f1f946d871397ef9ac53c1ff9798a5753bddbf40f5d
7
- data.tar.gz: 97cdf31a2684e938da9462d8f6d8f20ca0d6bd7170da449ef7e4eafa7c21633f452bcf6227daacb95541c37747e61aa99bcdb942a3c4e0aaa1f2400c06787d34
6
+ metadata.gz: 2cdf040047e4f4985c51d2bd1a0b3f207f4f8d6ee7c17f3732c5c93a09f89c2a842ec670e970ff5c8cb0f00dc0bf02fdbff9fe04b3d154b3881f4d52db17f209
7
+ data.tar.gz: 335b0e36faf70e2385bc806a5900a4eddaf66ab0e8fdf18b9c2850a041329408c89b0c8d6107eb29a596bcee7c3217522fc5a2907d625b202fec5ce61d19f0f7
data/README.rdoc CHANGED
@@ -32,4 +32,19 @@ TODO...
32
32
 
33
33
  bob.readings # => [<Reading 1>]
34
34
 
35
- Copyright (c) 2012 Culture Code Software Consulting. Released under the MIT license
35
+ === Upgrading from 2.3.x to 2.4.0
36
+
37
+ Version 2.4.0 now supports reading and querying against STI subclasses, even when the read and queried subclass don't
38
+ match. This requires you to migrate the `readings.readable_type` column data to the base class name of the stored class
39
+ name, as in versions prior to 2.4.0 the column stored the class name of whatever instance was being read, event STI
40
+ subclasses.
41
+
42
+ === Testing
43
+
44
+ There are multiple gemfiles available for testing against different Rails versions. Set `BUNDLE_GEMFILE` to target them, e.g.
45
+
46
+ bundle install
47
+ BUNDLE_GEMFILE=gemfiles/rails7.gemfile bundle exec rspec
48
+
49
+
50
+ Copyright (c) 2024 Culture Code Software Consulting. Released under the MIT license
@@ -6,13 +6,13 @@ module ActsAsReadable
6
6
  class_attribute :acts_as_readable_options
7
7
  self.acts_as_readable_options = options
8
8
 
9
- User.has_many :readings, :dependent => :delete_all
9
+ has_many :readings, :as => :readable, :dependent => :delete_all
10
+ has_many :readers, lambda { where :readings => {:state => 'read'} }, :through => :readings, :source => :user
10
11
 
11
- has_many :readings, :as => :readable, :dependent => :delete_all
12
- has_many :readers, lambda { where :readings => {:state => 'read'} }, :through => :readings, :source => :user
13
-
14
- scope :read_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.read_conditions(self, user))}
15
- scope :unread_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.unread_conditions(self, user))}
12
+ scope :read_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.read_conditions(self, user, :created_at))}
13
+ scope :unread_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.unread_conditions(self, user, :created_at))}
14
+ scope :latest_update_read_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.read_conditions(self, user, :updated_at))}
15
+ scope :latest_update_unread_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.unread_conditions(self, user, :updated_at))}
16
16
 
17
17
  extend ActsAsReadable::ClassMethods
18
18
  include ActsAsReadable::InstanceMethods
@@ -24,19 +24,19 @@ module ActsAsReadable
24
24
  end
25
25
 
26
26
  module HelperMethods
27
- def self.read_conditions(readable_class, user)
28
- ["(readable_type IS NULL AND COALESCE(#{readable_class.table_name}.updated_at < :all_read_at, :true))
29
- OR (readable_type IS NOT NULL AND COALESCE(readings.updated_at < :all_read_at, :true))
30
- OR (readings.state = 'read')",
31
- :all_read_at => all_read_at(readable_class, user), :true => true]
27
+ def self.read_conditions(readable_class, user, timestamp)
28
+ ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.#{timestamp} <= :all_read_at, FALSE))
29
+ OR (readings.state = 'unread' AND COALESCE(readings.updated_at <= :all_read_at, FALSE))
30
+ OR (readings.state = 'read' AND #{readable_class.table_name}.#{timestamp} <= readings.#{timestamp})",
31
+ :all_read_at => all_read_at(readable_class, user)]
32
32
  end
33
33
 
34
- def self.unread_conditions(readable_class, user)
34
+ def self.unread_conditions(readable_class, user, timestamp)
35
35
  # IF there is no reading and it has been updated since we last read all OR there is an unreading and we haven't read all since then
36
- ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.updated_at > :all_read_at, :true))
37
- OR (readings.state = 'unread' AND COALESCE(readings.updated_at > :all_read_at, :true))
38
- OR (readings.state = 'read' AND COALESCE(#{readable_class.table_name}.updated_at > readings.updated_at, :true))",
39
- :all_read_at => all_read_at(readable_class, user), :true => true]
36
+ ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.#{timestamp} > :all_read_at, TRUE))
37
+ OR (readings.state = 'unread' AND COALESCE(readings.updated_at > :all_read_at, TRUE))
38
+ OR (readings.state = 'read' AND #{readable_class.table_name}.#{timestamp} > readings.#{timestamp})",
39
+ :all_read_at => all_read_at(readable_class, user)]
40
40
  end
41
41
 
42
42
  def self.all_read_at(readable_class, user)
@@ -44,7 +44,11 @@ module ActsAsReadable
44
44
  end
45
45
 
46
46
  def self.outer_join_readings(scope, user)
47
- scope.joins("LEFT OUTER JOIN readings ON readings.readable_type = '#{scope.model.name}' AND readings.readable_id = #{scope.model.table_name}.id AND readings.user_id = #{user.id}")
47
+ scope.joins("LEFT OUTER JOIN readings ON readings.readable_type = '#{readable_type(scope.model)}' AND readings.readable_id = #{scope.model.table_name}.id AND readings.user_id = #{user.id}")
48
+ end
49
+
50
+ def self.readable_type(readable_class)
51
+ readable_class.base_class.name
48
52
  end
49
53
  end
50
54
 
@@ -52,7 +56,7 @@ module ActsAsReadable
52
56
  # Find all the readings of the readables by the user in a single SQL query and cache them in the readables for use in the view.
53
57
  def cache_readings_for(readables, user)
54
58
  readings = []
55
- Reading.where(:readable_type => name, :readable_id => readables.collect(&:id), :user_id => user.id).each do |reading|
59
+ Reading.where(:readable_type => HelperMethods.readable_type(self), :readable_id => readables.collect(&:id), :user_id => user.id).each do |reading|
56
60
  readings[reading.readable_id] = reading
57
61
  end
58
62
 
@@ -67,7 +71,7 @@ module ActsAsReadable
67
71
  # If a :cache option has been set in acts_as_readable, a timestamp will be updated on the user instead of creating individual readings for each record
68
72
  def read_by!(user)
69
73
  if user.has_attribute?(acts_as_readable_options[:cache])
70
- Reading.delete_all(:user_id => user.id, :readable_type => name)
74
+ Reading.where(:user_id => user.id, :readable_type => HelperMethods.readable_type(self)).delete_all
71
75
  user.update_column(acts_as_readable_options[:cache], Time.now)
72
76
  else
73
77
  unread_by(user).find_each do |record|
@@ -86,7 +90,7 @@ module ActsAsReadable
86
90
 
87
91
  def read_by!(user)
88
92
  # Find an existing reading and update the record so we can know when the thing was first read, and the last time we read it
89
- reading = Reading.find_or_initialize_by(:user_id => user.id, :readable_id => self.id, :readable_type => self.class.name)
93
+ reading = Reading.find_or_initialize_by(:user_id => user.id, :readable_id => self.id, :readable_type => HelperMethods.readable_type(self.class))
90
94
  reading.updated_at = Time.now # Explicitly set the read time to now in order to force a save in case we haven't changed anything else about the reading
91
95
  reading.state = :read
92
96
  reading.save!
@@ -96,7 +100,7 @@ module ActsAsReadable
96
100
  end
97
101
 
98
102
  def unread_by!(user)
99
- reading = Reading.find_or_initialize_by(:user_id => user.id, :readable_id => self.id, :readable_type => self.class.name)
103
+ reading = Reading.find_or_initialize_by(:user_id => user.id, :readable_id => self.id, :readable_type => HelperMethods.readable_type(self.class))
100
104
  reading.state = :unread
101
105
  reading.save!
102
106
  end
@@ -2,140 +2,250 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe 'acts_as_readable' do
5
- before(:each) do
6
- @comment = Comment.create
7
- @user = User.create
8
- end
9
-
10
- describe "the unread scope" do
11
- it "should not return records explicitly marked as read" do
12
- @comment.read_by! @user
13
- expect( Comment.unread_by(@user) ).not_to include(@comment)
14
- end
15
-
16
- it "should return records without readings if the user hasn't 'read all'" do
17
- expect( Comment.unread_by(@user) ).to include(@comment)
18
- end
19
-
20
- it "should return records explicitly marked as unread if the user hasn't 'read all'" do
21
- @comment.unread_by! @user
22
- expect( Comment.unread_by(@user) ).to include(@comment)
23
- end
24
-
25
- it "should return records explicitly marked as unread if the user has 'read all' before the record was marked unread" do
26
- Comment.read_by! @user
27
- @comment.unread_by! @user
28
- expect( Comment.unread_by(@user) ).to include(@comment)
29
- end
30
-
31
- it "should not return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
32
- @comment.unread_by! @user
33
- Comment.read_by! @user
34
- expect( Comment.unread_by(@user) ).not_to include(@comment)
35
- end
36
-
37
- it "should return records that have been updated since they were last read" do
38
- @comment.read_by! @user
39
- @comment.touch
40
- expect( Comment.unread_by(@user) ).to include(@comment)
41
- end
42
-
43
- it "should return records that have been updated since they were last unread" do
44
- @comment.unread_by! @user
45
- @comment.touch
46
- expect( Comment.unread_by(@user) ).to include(@comment)
5
+ shared_examples_for 'a readable class' do |readable_class, queryable_class|
6
+ before(:each) do
7
+ @readable = readable_class.create
8
+ @queryable = @readable.becomes!(queryable_class)
9
+ @user = User.create
10
+ end
11
+
12
+ describe "the unread scope" do
13
+ it "should not return records explicitly marked as read" do
14
+ @readable.read_by! @user
15
+ expect(queryable_class.unread_by(@user)).not_to include(@queryable)
16
+ end
17
+
18
+ it "should return records without readings if the user hasn't 'read all'" do
19
+ expect(queryable_class.unread_by(@user)).to include(@queryable)
20
+ end
21
+
22
+ it "should return records explicitly marked as unread if the user hasn't 'read all'" do
23
+ @readable.unread_by! @user
24
+ expect(queryable_class.unread_by(@user)).to include(@queryable)
25
+ end
26
+
27
+ it "should return records explicitly marked as unread if the user has 'read all' before the record was marked unread" do
28
+ readable_class.read_by! @user
29
+ @readable.unread_by! @user
30
+ expect(queryable_class.unread_by(@user)).to include(@queryable)
31
+ end
32
+
33
+ it "should return records explicitly marked as unread after the user 'read all'" do
34
+ @readable.read_by! @user
35
+ readable_class.read_by! @user
36
+ @readable.unread_by! @user
37
+ expect(queryable_class.unread_by(@user)).to include(@queryable)
38
+ end
39
+
40
+ it "should not return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
41
+ @readable.unread_by! @user
42
+ readable_class.read_by! @user
43
+ expect(queryable_class.unread_by(@user)).not_to include(@queryable)
44
+ end
45
+
46
+ it "should not return records that have been updated since they were last read" do
47
+ @readable.read_by! @user
48
+ @readable.touch
49
+ expect(queryable_class.unread_by(@user)).not_to include(@queryable)
50
+ end
51
+
52
+ it "should return records that have been updated since they were last unread" do
53
+ @readable.unread_by! @user
54
+ @readable.touch
55
+ expect(queryable_class.unread_by(@user)).to include(@queryable)
56
+ end
57
+ end
58
+
59
+ describe "the read scope" do
60
+ it "should not return records without readings if the user has not 'read all'" do
61
+ expect(queryable_class.read_by(@user)).not_to include(@queryable)
62
+ end
63
+
64
+ it "should return records without readings if the user has 'read all' since the last time the record was updated" do
65
+ readable_class.read_by! @user
66
+ expect(queryable_class.read_by(@user)).to include(@queryable)
67
+ end
68
+
69
+ it "should return records explicitly marked as read if the user hasn't 'read all'" do
70
+ @readable.read_by! @user
71
+ expect(queryable_class.read_by(@user)).to include(@queryable)
72
+ end
73
+
74
+ it "should return records explicitly marked as read if the user has 'read all' before the record was marked read" do
75
+ readable_class.read_by! @user
76
+ @readable.read_by! @user
77
+ expect(queryable_class.read_by(@user)).to include(@queryable)
78
+ end
79
+
80
+ it "should not return records explicitly marked as unread after the user 'read all'" do
81
+ @readable.read_by! @user
82
+ readable_class.read_by! @user
83
+ @readable.unread_by! @user
84
+ expect(queryable_class.read_by(@user)).not_to include(@queryable)
85
+ end
86
+
87
+ it "should return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
88
+ @readable.unread_by! @user
89
+ readable_class.read_by! @user
90
+ expect(queryable_class.read_by(@user)).to include(@queryable)
91
+ end
92
+
93
+ it "should return records that have been updated since they were last read" do
94
+ @readable.read_by! @user
95
+ @readable.touch
96
+ expect(queryable_class.read_by(@user)).to include(@queryable)
97
+ end
98
+ end
99
+
100
+ describe "the latest_update_read_by scope" do
101
+ it "should return records without readings if the user has 'read all' since the last time the record was updated" do
102
+ readable_class.read_by! @user
103
+ expect(queryable_class.latest_update_read_by(@user)).to include(@queryable)
104
+ end
105
+
106
+ it "should return records explicitly marked as read if the user hasn't 'read all'" do
107
+ @readable.read_by! @user
108
+ expect(queryable_class.latest_update_read_by(@user)).to include(@queryable)
109
+ end
110
+
111
+ it "should return records explicitly marked as read if the user has 'read all' before the record was marked unread" do
112
+ readable_class.read_by! @user
113
+ @readable.read_by! @user
114
+ expect(queryable_class.latest_update_read_by(@user)).to include(@queryable)
115
+ end
116
+
117
+ it "should return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
118
+ @readable.unread_by! @user
119
+ readable_class.read_by! @user
120
+ expect(queryable_class.latest_update_read_by(@user)).to include(@queryable)
121
+ end
122
+
123
+ it "should not return records that have been updated since they were last read" do
124
+ @readable.read_by! @user
125
+ @readable.touch
126
+ expect(queryable_class.latest_update_read_by(@user)).not_to include(@queryable)
127
+ end
128
+
129
+ it "should return records updated after being read after a bulk read_by" do
130
+ @readable.read_by! @user
131
+ @readable.touch
132
+ readable_class.read_by! @user
133
+ expect(queryable_class.latest_update_read_by(@user)).to include(@queryable)
134
+ end
135
+ end
136
+
137
+ describe "the latest_update_unread_by scope" do
138
+ it "should not return records explicitly marked as read" do
139
+ @readable.read_by! @user
140
+ expect(queryable_class.latest_update_unread_by(@user)).not_to include(@queryable)
141
+ end
142
+
143
+ it "should return records without readings if the user hasn't 'read all'" do
144
+ expect(queryable_class.latest_update_unread_by(@user)).to include(@queryable)
145
+ end
146
+
147
+ it "should return records explicitly marked as unread if the user hasn't 'read all'" do
148
+ @readable.unread_by! @user
149
+ expect(queryable_class.latest_update_unread_by(@user)).to include(@queryable)
150
+ end
151
+
152
+ it "should return records explicitly marked as unread if the user has 'read all' before the record was marked unread" do
153
+ readable_class.read_by! @user
154
+ @readable.unread_by! @user
155
+ expect(queryable_class.latest_update_unread_by(@user)).to include(@queryable)
156
+ end
157
+
158
+ it "should not return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
159
+ @readable.unread_by! @user
160
+ readable_class.read_by! @user
161
+ expect(queryable_class.latest_update_unread_by(@user)).not_to include(@queryable)
162
+ end
163
+
164
+ it "should return records that have been updated since they were last read" do
165
+ @readable.read_by! @user
166
+ @readable.touch
167
+ expect(queryable_class.latest_update_unread_by(@user)).to include(@queryable)
168
+ end
169
+ end
170
+
171
+ describe "when checking a specific record for read_by?" do
172
+ it "should return true if the record hasn't explicitly been read, but the user has 'read all' since the record was created" do
173
+ readable_class.read_by! @user
174
+ expect(@queryable.read_by?(@user)).to be_truthy
175
+ end
176
+
177
+ it "should return true if the record hasn't explicitly been read and the user has 'read all' since the record was created but not since it was updated" do
178
+ readable_class.read_by! @user
179
+ @readable.touch
180
+ expect(@queryable.read_by?(@user)).to be_truthy
181
+ end
182
+
183
+ it "should return true if the record has been explicitly marked as read and the user hasn't 'read all'" do
184
+ @readable.read_by! @user
185
+ expect(@queryable.read_by?(@user)).to be_truthy
186
+ end
187
+
188
+ it "should return false if the user 'read all' before and then marked the record as unread" do
189
+ readable_class.read_by! @user
190
+ @readable.unread_by! @user
191
+ expect(@queryable.read_by?(@user)).to be_falsey
192
+ end
193
+
194
+ it "should return true if the user has explicitly marked it as unread and then 'reads all'" do
195
+ @readable.unread_by! @user
196
+ readable_class.read_by! @user
197
+ expect(@queryable.read_by?(@user)).to be_truthy
198
+ end
199
+ end
200
+
201
+ describe "when checking a specific record for latest_update_read_by?" do
202
+ it "should return true if the record hasn't explicitly been read, but the user has 'read all' since the record was updated" do
203
+ readable_class.read_by! @user
204
+ expect(@queryable.latest_update_read_by?(@user)).to be_truthy
205
+ end
206
+
207
+ it "should return false if the record hasn't explicitly been read and the user has 'read all' since the record was created but not since it was updated" do
208
+ readable_class.read_by! @user
209
+ @readable.touch
210
+ expect(@queryable.latest_update_read_by?(@user)).to be_falsey
211
+ end
212
+
213
+ it "should return true if the record has been explicitly marked as read and the user hasn't 'read all'" do
214
+ @readable.read_by! @user
215
+ expect(@queryable.latest_update_read_by?(@user)).to be_truthy
216
+ end
217
+
218
+ it "should return false if the user 'read all' before and then marked the record as unread" do
219
+ readable_class.read_by! @user
220
+ @readable.unread_by! @user
221
+ expect(@queryable.latest_update_read_by?(@user)).to be_falsey
222
+ end
223
+
224
+ it "should return true if the user has explicitly marked it as unread and then 'reads all'" do
225
+ @readable.unread_by! @user
226
+ readable_class.read_by! @user
227
+ expect(@queryable.latest_update_read_by?(@user)).to be_truthy
228
+ end
229
+
230
+ it "should return false if the user 'read all' before and then marked the record as unread using cached readings" do
231
+ readable_class.read_by! @user
232
+ @readable.unread_by! @user
233
+ readable_class.cache_readings_for([@readable], @user)
234
+ expect(@queryable.latest_update_read_by?(@user)).to be_falsey
235
+ end
47
236
  end
48
237
  end
49
238
 
50
- describe "the read scope" do
51
- it "should return records without readings if the user has 'read all' since the last time the record was updated" do
52
- Comment.read_by! @user
53
- expect( Comment.read_by(@user) ).to include(@comment)
54
- end
55
-
56
- it "should return records explicitly marked as read if the user hasn't 'read all'" do
57
- @comment.read_by! @user
58
- expect( Comment.read_by(@user) ).to include(@comment)
59
- end
60
-
61
- it "should return records explicitly marked as read if the user has 'read all' before the record was marked unread" do
62
- Comment.read_by! @user
63
- @comment.read_by! @user
64
- expect( Comment.read_by(@user) ).to include(@comment)
65
- end
66
-
67
- it "should return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
68
- @comment.unread_by! @user
69
- Comment.read_by! @user
70
- expect( Comment.read_by(@user) ).to include(@comment)
71
- end
239
+ context 'the readable is a base class' do
240
+ it_behaves_like 'a readable class', Comment, Comment
72
241
  end
73
242
 
74
- describe "when checking a specific record for read_by?" do
75
- it "should return true if the record hasn't explicitly been read, but the user has 'read all' since the record was created" do
76
- Comment.read_by! @user
77
- expect( @comment.read_by?(@user) ).to be_truthy
78
- end
79
-
80
- it "should return true if the record hasn't explicitly been read and the user has 'read all' since the record was created but not since it was updated" do
81
- Comment.read_by! @user
82
- @comment.touch
83
- expect( @comment.read_by?(@user) ).to be_truthy
84
- end
85
-
86
- it "should return true if the record has been explicitly marked as read and the user hasn't 'read all'" do
87
- @comment.read_by! @user
88
- expect( @comment.read_by?(@user) ).to be_truthy
89
- end
90
-
91
- it "should return false if the user 'read all' before and then marked the record as unread" do
92
- Comment.read_by! @user
93
- @comment.unread_by! @user
94
- expect( @comment.read_by?(@user) ).to be_falsey
95
- end
96
-
97
- it "should return true if the user has explicitly marked it as unread and then 'reads all'" do
98
- @comment.unread_by! @user
99
- Comment.read_by! @user
100
- expect( @comment.read_by?(@user) ).to be_truthy
101
- end
243
+ context 'when reading an STI record' do
244
+ it_behaves_like 'a readable class', PrivateComment, PrivateComment
102
245
  end
103
246
 
104
- describe "when checking a specific record for latest_update_read_by?" do
105
- it "should return true if the record hasn't explicitly been read, but the user has 'read all' since the record was updated" do
106
- Comment.read_by! @user
107
- expect( @comment.latest_update_read_by?(@user) ).to be_truthy
108
- end
109
-
110
- it "should return false if the record hasn't explicitly been read and the user has 'read all' since the record was created but not since it was updated" do
111
- Comment.read_by! @user
112
- @comment.touch
113
- expect( @comment.latest_update_read_by?(@user) ).to be_falsey
114
- end
115
-
116
- it "should return true if the record has been explicitly marked as read and the user hasn't 'read all'" do
117
- @comment.read_by! @user
118
- expect( @comment.latest_update_read_by?(@user) ).to be_truthy
119
- end
120
-
121
- it "should return false if the user 'read all' before and then marked the record as unread" do
122
- Comment.read_by! @user
123
- @comment.unread_by! @user
124
- expect( @comment.latest_update_read_by?(@user) ).to be_falsey
125
- end
126
-
127
- it "should return true if the user has explicitly marked it as unread and then 'reads all'" do
128
- @comment.unread_by! @user
129
- Comment.read_by! @user
130
- expect( @comment.latest_update_read_by?(@user) ).to be_truthy
131
- end
132
-
133
- it "should return false if the user 'read all' before and then marked the record as unread using cached readings" do
134
- Comment.read_by! @user
135
- @comment.unread_by! @user
136
- Comment.cache_readings_for([@comment], @user)
137
- expect( @comment.latest_update_read_by?(@user) ).to be_falsey
138
- end
247
+ context 'when reading an STI record and querying against the base class record' do
248
+ it_behaves_like 'a readable class', PrivateComment, Comment
139
249
  end
140
250
  end
141
251
  `dropdb acts_as_readable_test`
data/spec/spec_helper.rb CHANGED
@@ -2,7 +2,14 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
2
  require 'active_record'
3
3
  require 'acts_as_readable'
4
4
 
5
- ActiveRecord::Base.establish_connection(:adapter => "postgresql", :database => "acts_as_readable_test") # Not using sqlite3 for testing because of its ridiculous boolean handling
5
+ ActiveRecord::Base.establish_connection(
6
+ :adapter => "postgresql",
7
+ :host => "localhost",
8
+ :encoding => "unicode",
9
+ :database => "acts_as_readable_test",
10
+ :username => ENV["POSTGRES_USER"],
11
+ :password => ENV["POSTGRES_PASSWORD"]
12
+ )
6
13
 
7
14
  ActiveRecord::Schema.define(:version => 0) do
8
15
  create_table :users, :force => true do |t|
@@ -10,6 +17,7 @@ ActiveRecord::Schema.define(:version => 0) do
10
17
  end
11
18
 
12
19
  create_table :comments, :force => true do |t|
20
+ t.string :type
13
21
  t.timestamps
14
22
  end
15
23
 
@@ -28,6 +36,9 @@ class Comment < ActiveRecord::Base
28
36
  acts_as_readable :cache => :comments_read_at
29
37
  end
30
38
 
39
+ class PrivateComment < Comment
40
+ end
41
+
31
42
 
32
43
  def debug_queries
33
44
  logger = ActiveRecord::Base.logger
metadata CHANGED
@@ -1,31 +1,65 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_readable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Jakobsen
8
8
  - Ryan Wallace
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-09-08 00:00:00.000000000 Z
12
+ date: 2024-03-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">"
19
+ - !ruby/object:Gem::Version
20
+ version: '5'
21
+ - - "<"
19
22
  - !ruby/object:Gem::Version
20
- version: '4.0'
23
+ version: '8'
21
24
  type: :runtime
22
25
  prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">"
29
+ - !ruby/object:Gem::Version
30
+ version: '5'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '8'
34
+ - !ruby/object:Gem::Dependency
35
+ name: pg
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ type: :development
42
+ prerelease: false
43
+ version_requirements: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec-rails
50
+ requirement: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '4'
55
+ type: :development
56
+ prerelease: false
23
57
  version_requirements: !ruby/object:Gem::Requirement
24
58
  requirements:
25
59
  - - "~>"
26
60
  - !ruby/object:Gem::Version
27
- version: '4.0'
28
- description:
61
+ version: '4'
62
+ description:
29
63
  email: contact@culturecode.ca
30
64
  executables: []
31
65
  extensions: []
@@ -42,7 +76,7 @@ files:
42
76
  homepage: http://github.com/culturecode/acts_as_readable
43
77
  licenses: []
44
78
  metadata: {}
45
- post_install_message:
79
+ post_install_message:
46
80
  rdoc_options: []
47
81
  require_paths:
48
82
  - lib
@@ -57,8 +91,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
91
  - !ruby/object:Gem::Version
58
92
  version: '0'
59
93
  requirements: []
60
- rubygems_version: 3.0.8
61
- signing_key:
94
+ rubygems_version: 3.3.23
95
+ signing_key:
62
96
  specification_version: 4
63
97
  summary: Allows records to be marked as readable. Optimized for bulk, 'mark all as
64
98
  read' operations