acts_as_readable 2.1.1 → 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
- SHA1:
3
- metadata.gz: 3d8d2b78dd717f7f730d3421f544bd3ee2364e27
4
- data.tar.gz: 09ffc7e7cfd1ef5107a0dc42c36fc9c39ac99c6c
2
+ SHA256:
3
+ metadata.gz: 28febc32aaf17802d8db7b624fc3dce68bf6620d438b8a2bab8c7aa2cc8620ca
4
+ data.tar.gz: 6ad32b0cf210c6806c90611e6cc2575a5d710b87e65bd8d0d08ef35bde28627b
5
5
  SHA512:
6
- metadata.gz: cc2801ab538a63cfc9840465eb850b1e894f9692d4a8606fb0f7001c1d557b79208469d90535d98439393dd6c6f3922917a19dedf5d3ce5c00ce387c96373f5b
7
- data.tar.gz: 420399273b939da92a3f93375a4ccf7eb57b2a0829928f57903d0d92dd6961a3f0ae70fa873dc99bc5ca463c8e5b0a8704ee098041336d0c7317f73b7cfa9173
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,31 +8,37 @@ 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
19
21
  end
22
+
23
+ def acts_as_reader
24
+ has_many :readings, :dependent => :delete_all
25
+ end
20
26
  end
21
27
 
22
28
  module HelperMethods
23
- def self.read_conditions(readable_class, user)
24
- ["(readable_type IS NULL AND COALESCE(#{readable_class.table_name}.updated_at < :all_read_at, :true))
25
- OR (readable_type IS NOT NULL AND COALESCE(readings.updated_at < :all_read_at, :true))
26
- OR (readings.state = 'read')",
27
- :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)]
28
34
  end
29
35
 
30
- def self.unread_conditions(readable_class, user)
36
+ def self.unread_conditions(readable_class, user, timestamp)
31
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
32
- ["(readings.state IS NULL AND COALESCE(#{readable_class.table_name}.updated_at > :all_read_at, :true))
33
- OR (readings.state = 'unread' AND COALESCE(readings.updated_at > :all_read_at, :true))
34
- OR (readings.state = 'read' AND COALESCE(#{readable_class.table_name}.updated_at > readings.updated_at, :true))",
35
- :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)]
36
42
  end
37
43
 
38
44
  def self.all_read_at(readable_class, user)
@@ -63,7 +69,7 @@ module ActsAsReadable
63
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
64
70
  def read_by!(user)
65
71
  if user.has_attribute?(acts_as_readable_options[:cache])
66
- Reading.delete_all(:user_id => user.id, :readable_type => name)
72
+ Reading.where(:user_id => user.id, :readable_type => name).delete_all
67
73
  user.update_column(acts_as_readable_options[:cache], Time.now)
68
74
  else
69
75
  unread_by(user).find_each do |record|
@@ -129,4 +135,3 @@ module ActsAsReadable
129
135
  end
130
136
  end
131
137
  end
132
-
@@ -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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: acts_as_readable
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicholas Jakobsen
@@ -9,22 +9,56 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-01-30 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'
61
+ version: '4'
28
62
  description:
29
63
  email: contact@culturecode.ca
30
64
  executables: []
@@ -57,8 +91,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
91
  - !ruby/object:Gem::Version
58
92
  version: '0'
59
93
  requirements: []
60
- rubyforge_project:
61
- rubygems_version: 2.2.1
94
+ rubygems_version: 3.3.23
62
95
  signing_key:
63
96
  specification_version: 4
64
97
  summary: Allows records to be marked as readable. Optimized for bulk, 'mark all as