acts_as_readable 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e2eb3570785a65d3e80567534270dae5825eceb07fdeec498764c2065f129892
4
- data.tar.gz: c9bacbe67acb169365404c423640fd4f25d9536315228d014bea8c6e7e100987
3
+ metadata.gz: 28febc32aaf17802d8db7b624fc3dce68bf6620d438b8a2bab8c7aa2cc8620ca
4
+ data.tar.gz: 6ad32b0cf210c6806c90611e6cc2575a5d710b87e65bd8d0d08ef35bde28627b
5
5
  SHA512:
6
- metadata.gz: c7ddc495d6010d7748b134c731908c1a2e71b88b4cc86b8f694729e4bc1c83659e10bf0b0547801012124f1f946d871397ef9ac53c1ff9798a5753bddbf40f5d
7
- data.tar.gz: 97cdf31a2684e938da9462d8f6d8f20ca0d6bd7170da449ef7e4eafa7c21633f452bcf6227daacb95541c37747e61aa99bcdb942a3c4e0aaa1f2400c06787d34
6
+ metadata.gz: 42f65a6d0f3071710fa9cbdb4b65c507f0a753dc299294989d5c908148512e3443514f4f500555be7fa01fcf3ccb618435a9a8a5197398668f3319d8d0b0daaf
7
+ data.tar.gz: cbd81ccf4ea4d53f58ea46c67cf5d625daa83909476d84597eb4caf6c0ceae4f826579543240cee80bad5d231de4038072a3f59f5809d7c219117355418556a6
data/README.rdoc CHANGED
@@ -32,4 +32,12 @@ TODO...
32
32
 
33
33
  bob.readings # => [<Reading 1>]
34
34
 
35
+ === Testing
36
+
37
+ There are multiple gemfiles available for testing against different Rails versions. Set `BUNDLE_GEMFILE` to target them, e.g.
38
+
39
+ bundle install
40
+ BUNDLE_GEMFILE=gemfiles/rails7.gemfile bundle exec rspec
41
+
42
+
35
43
  Copyright (c) 2012 Culture Code Software Consulting. Released under the MIT license
@@ -8,11 +8,13 @@ module ActsAsReadable
8
8
 
9
9
  User.has_many :readings, :dependent => :delete_all
10
10
 
11
- has_many :readings, :as => :readable, :dependent => :delete_all
12
- has_many :readers, lambda { where :readings => {:state => 'read'} }, :through => :readings, :source => :user
11
+ has_many :readings, :as => :readable, :dependent => :delete_all
12
+ has_many :readers, lambda { where :readings => {:state => 'read'} }, :through => :readings, :source => :user
13
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))}
14
+ scope :read_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.read_conditions(self, user, :created_at))}
15
+ scope :unread_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.unread_conditions(self, user, :created_at))}
16
+ scope :latest_update_read_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.read_conditions(self, user, :updated_at))}
17
+ scope :latest_update_unread_by, lambda {|user| ActsAsReadable::HelperMethods.outer_join_readings(all, user).where(ActsAsReadable::HelperMethods.unread_conditions(self, user, :updated_at))}
16
18
 
17
19
  extend ActsAsReadable::ClassMethods
18
20
  include ActsAsReadable::InstanceMethods
@@ -24,19 +26,19 @@ module ActsAsReadable
24
26
  end
25
27
 
26
28
  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]
29
+ def self.read_conditions(readable_class, user, timestamp)
30
+ ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.#{timestamp} <= :all_read_at, FALSE))
31
+ OR (readings.state = 'unread' AND COALESCE(readings.updated_at <= :all_read_at, FALSE))
32
+ OR (readings.state = 'read' AND #{readable_class.table_name}.#{timestamp} <= readings.#{timestamp})",
33
+ :all_read_at => all_read_at(readable_class, user)]
32
34
  end
33
35
 
34
- def self.unread_conditions(readable_class, user)
36
+ def self.unread_conditions(readable_class, user, timestamp)
35
37
  # 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]
38
+ ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.#{timestamp} > :all_read_at, TRUE))
39
+ OR (readings.state = 'unread' AND COALESCE(readings.updated_at > :all_read_at, TRUE))
40
+ OR (readings.state = 'read' AND #{readable_class.table_name}.#{timestamp} > readings.#{timestamp})",
41
+ :all_read_at => all_read_at(readable_class, user)]
40
42
  end
41
43
 
42
44
  def self.all_read_at(readable_class, user)
@@ -67,7 +69,7 @@ module ActsAsReadable
67
69
  # 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
70
  def read_by!(user)
69
71
  if user.has_attribute?(acts_as_readable_options[:cache])
70
- Reading.delete_all(:user_id => user.id, :readable_type => name)
72
+ Reading.where(:user_id => user.id, :readable_type => name).delete_all
71
73
  user.update_column(acts_as_readable_options[:cache], Time.now)
72
74
  else
73
75
  unread_by(user).find_each do |record|
@@ -28,16 +28,23 @@ describe 'acts_as_readable' do
28
28
  expect( Comment.unread_by(@user) ).to include(@comment)
29
29
  end
30
30
 
31
+ it "should return records explicitly marked as unread after the user 'read all'" do
32
+ @comment.read_by! @user
33
+ Comment.read_by! @user
34
+ @comment.unread_by! @user
35
+ expect( Comment.unread_by(@user) ).to include(@comment)
36
+ end
37
+
31
38
  it "should not return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
32
39
  @comment.unread_by! @user
33
40
  Comment.read_by! @user
34
41
  expect( Comment.unread_by(@user) ).not_to include(@comment)
35
42
  end
36
43
 
37
- it "should return records that have been updated since they were last read" do
44
+ it "should not return records that have been updated since they were last read" do
38
45
  @comment.read_by! @user
39
46
  @comment.touch
40
- expect( Comment.unread_by(@user) ).to include(@comment)
47
+ expect( Comment.unread_by(@user) ).not_to include(@comment)
41
48
  end
42
49
 
43
50
  it "should return records that have been updated since they were last unread" do
@@ -48,6 +55,10 @@ describe 'acts_as_readable' do
48
55
  end
49
56
 
50
57
  describe "the read scope" do
58
+ it "should not return records without readings if the user has not 'read all'" do
59
+ expect( Comment.read_by(@user) ).not_to include(@comment)
60
+ end
61
+
51
62
  it "should return records without readings if the user has 'read all' since the last time the record was updated" do
52
63
  Comment.read_by! @user
53
64
  expect( Comment.read_by(@user) ).to include(@comment)
@@ -58,17 +69,101 @@ describe 'acts_as_readable' do
58
69
  expect( Comment.read_by(@user) ).to include(@comment)
59
70
  end
60
71
 
61
- it "should return records explicitly marked as read if the user has 'read all' before the record was marked unread" do
72
+ it "should return records explicitly marked as read if the user has 'read all' before the record was marked read" do
62
73
  Comment.read_by! @user
63
74
  @comment.read_by! @user
64
75
  expect( Comment.read_by(@user) ).to include(@comment)
65
76
  end
66
77
 
78
+ it "should not return records explicitly marked as unread after the user 'read all'" do
79
+ @comment.read_by! @user
80
+ Comment.read_by! @user
81
+ @comment.unread_by! @user
82
+ expect( Comment.read_by(@user) ).not_to include(@comment)
83
+ end
84
+
67
85
  it "should return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
68
86
  @comment.unread_by! @user
69
87
  Comment.read_by! @user
70
88
  expect( Comment.read_by(@user) ).to include(@comment)
71
89
  end
90
+
91
+ it "should return records that have been updated since they were last read" do
92
+ @comment.read_by! @user
93
+ @comment.touch
94
+ expect( Comment.read_by(@user) ).to include(@comment)
95
+ end
96
+ end
97
+
98
+ describe "the latest_update_read_by scope" do
99
+ it "should return records without readings if the user has 'read all' since the last time the record was updated" do
100
+ Comment.read_by! @user
101
+ expect( Comment.latest_update_read_by(@user) ).to include(@comment)
102
+ end
103
+
104
+ it "should return records explicitly marked as read if the user hasn't 'read all'" do
105
+ @comment.read_by! @user
106
+ expect( Comment.latest_update_read_by(@user) ).to include(@comment)
107
+ end
108
+
109
+ it "should return records explicitly marked as read if the user has 'read all' before the record was marked unread" do
110
+ Comment.read_by! @user
111
+ @comment.read_by! @user
112
+ expect( Comment.latest_update_read_by(@user) ).to include(@comment)
113
+ end
114
+
115
+ it "should return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
116
+ @comment.unread_by! @user
117
+ Comment.read_by! @user
118
+ expect( Comment.latest_update_read_by(@user) ).to include(@comment)
119
+ end
120
+
121
+ it "should not return records that have been updated since they were last read" do
122
+ @comment.read_by! @user
123
+ @comment.touch
124
+ expect( Comment.latest_update_read_by(@user) ).not_to include(@comment)
125
+ end
126
+
127
+ it "should return records updated after being read after a bulk read_by" do
128
+ @comment.read_by! @user
129
+ @comment.touch
130
+ Comment.read_by! @user
131
+ expect( Comment.latest_update_read_by(@user) ).to include(@comment)
132
+ end
133
+ end
134
+
135
+ describe "the latest_update_unread_by scope" do
136
+ it "should not return records explicitly marked as read" do
137
+ @comment.read_by! @user
138
+ expect( Comment.latest_update_unread_by(@user) ).not_to include(@comment)
139
+ end
140
+
141
+ it "should return records without readings if the user hasn't 'read all'" do
142
+ expect( Comment.latest_update_unread_by(@user) ).to include(@comment)
143
+ end
144
+
145
+ it "should return records explicitly marked as unread if the user hasn't 'read all'" do
146
+ @comment.unread_by! @user
147
+ expect( Comment.latest_update_unread_by(@user) ).to include(@comment)
148
+ end
149
+
150
+ it "should return records explicitly marked as unread if the user has 'read all' before the record was marked unread" do
151
+ Comment.read_by! @user
152
+ @comment.unread_by! @user
153
+ expect( Comment.latest_update_unread_by(@user) ).to include(@comment)
154
+ end
155
+
156
+ it "should not return records explicitly marked as unread if the user has 'read all' after the record was marked unread" do
157
+ @comment.unread_by! @user
158
+ Comment.read_by! @user
159
+ expect( Comment.latest_update_unread_by(@user) ).not_to include(@comment)
160
+ end
161
+
162
+ it "should return records that have been updated since they were last read" do
163
+ @comment.read_by! @user
164
+ @comment.touch
165
+ expect( Comment.latest_update_unread_by(@user) ).to include(@comment)
166
+ end
72
167
  end
73
168
 
74
169
  describe "when checking a specific record for read_by?" do
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|
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.3.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-02-22 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