unread 0.4.0 → 0.5.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
  SHA1:
3
- metadata.gz: 62f6d5dbe191941fe9f5b358318fefbf93ad0c20
4
- data.tar.gz: 80e1d361fc919f39f33142283b2dfe8d1d9376a1
3
+ metadata.gz: 641b3b24fbf159c92f7b4a29485b987454cd382f
4
+ data.tar.gz: 2aa121f6822aad813d903014bf3284b7323a8cbb
5
5
  SHA512:
6
- metadata.gz: 8808316873efd20db90cb45b9bbf14e4bc6fb3336f69d3f2480bfe8feaee04a21c39a44672d28c892e6365ceb26440525c36283e27d6508baec32f8e2aa72246
7
- data.tar.gz: a55db92bee6d0b5969cb244655137e08afc7438a8abedbcb65f92a44d05c77ce60dad18d677e64c745b3b831063e08a5076773d717773d30a1685f74d2735f1e
6
+ metadata.gz: fd852349b8f7365896c4b2d35e88f18dd7cf3ce3275f52dc0b8c55a24334306d4a6cb22ac98d356d80b92588ebbe9b78d0cd9924785f7524a32055aec0d0c598
7
+ data.tar.gz: 80038ecb572e07cc0ca3e1e21ae4e2879f21d80d13d03c6d6c524a7000f0098bac258d5b3f142a71cbf20b384c80c3e579ea4e6e08c1228eba351aa6e7251a8c
@@ -1,12 +1,15 @@
1
1
  language: ruby
2
2
  rvm:
3
3
  - 1.9.3
4
- - 2.0.0
5
- - 2.1.1
4
+ - 2.0
5
+ - 2.1
6
+ - 2.2
6
7
  gemfile:
7
8
  - ci/Gemfile-rails-3-0
8
9
  - ci/Gemfile-rails-3-1
9
10
  - ci/Gemfile-rails-3-2
10
11
  - ci/Gemfile-rails-4-0
11
12
  - ci/Gemfile-rails-4-1
13
+ - ci/Gemfile-rails-4-2
12
14
  before_install: gem update bundler
15
+ sudo: false
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2010-2014 Georg Ledermann
3
+ Copyright (c) 2010-2015 Georg Ledermann
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -140,4 +140,4 @@ There are two other gems/plugins doing a similar job:
140
140
  Unfortunately, both of them have a lack of performance, because they calculate the unread records doing a `find(:all)`, which should be avoided for a large amount of records. This gem is based on a timestamp algorithm and therefore it's very fast.
141
141
 
142
142
 
143
- Copyright (c) 2010-2014 [Georg Ledermann](http://www.georg-ledermann.de), released under the MIT license
143
+ Copyright (c) 2010-2015 [Georg Ledermann](http://www.georg-ledermann.de), released under the MIT license
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activerecord', '~> 4.2.0'
4
+ gem 'sqlite3'
5
+ gem 'timecop'
6
+ gem 'rake'
7
+ gem 'rspec'
8
+ gem 'simplecov'
9
+ gem 'coveralls'
@@ -1,9 +1,8 @@
1
1
  class UnreadMigration < ActiveRecord::Migration
2
2
  def self.up
3
- create_table :read_marks, :force => true do |t|
4
- t.integer :readable_id
5
- t.integer :user_id, :null => false
6
- t.string :readable_type, :null => false, :limit => 20
3
+ create_table :read_marks, force: true do |t|
4
+ t.references :readable, polymorphic: { null: false }
5
+ t.references :user, null: false
7
6
  t.datetime :timestamp
8
7
  end
9
8
 
@@ -4,7 +4,7 @@ module Unread
4
4
  end
5
5
 
6
6
  module Base
7
- def acts_as_reader
7
+ def acts_as_reader(options={})
8
8
  ReadMark.belongs_to :user, :class_name => self.to_s
9
9
 
10
10
  has_many :read_marks, :dependent => :delete_all, :foreign_key => 'user_id', :inverse_of => :user
@@ -18,6 +18,9 @@ module Unread
18
18
  end
19
19
  end
20
20
 
21
+ ReadMark.reader_class = self
22
+ ReadMark.reader_options = options
23
+
21
24
  include Reader::InstanceMethods
22
25
  end
23
26
 
@@ -11,9 +11,18 @@ class ReadMark < ActiveRecord::Base
11
11
  scope :older_than, lambda { |timestamp| where([ 'timestamp < ?', timestamp ]) }
12
12
 
13
13
  # Returns the class defined by acts_as_reader
14
- def self.reader_class
15
- reflect_on_all_associations(:belongs_to).find { |assoc| assoc.name == :user }.try(:klass)
16
- end
14
+ class_attribute :reader_class
15
+ class_attribute :reader_options
17
16
 
17
+ # Returns the classes defined by acts_as_readable
18
18
  class_attribute :readable_classes
19
+
20
+ def self.reader_scope
21
+ result = reader_class
22
+
23
+ Array(reader_options[:scopes]).each do |scope|
24
+ result = result.send(scope)
25
+ end
26
+ result
27
+ end
19
28
  end
@@ -18,12 +18,19 @@ module Unread
18
18
 
19
19
  def mark_array_as_read(array, user)
20
20
  ReadMark.transaction do
21
+ global_timestamp = user.read_mark_global(self).try(:timestamp)
22
+
21
23
  array.each do |obj|
22
24
  raise ArgumentError unless obj.is_a?(self)
25
+ timestamp = obj.send(readable_options[:on])
23
26
 
24
- rm = obj.read_marks.where(:user_id => user.id).first || obj.read_marks.build(:user_id => user.id)
25
- rm.timestamp = obj.send(readable_options[:on])
26
- rm.save!
27
+ if global_timestamp && global_timestamp >= timestamp
28
+ # The object is implicitly marked as read, so there is nothing to do
29
+ else
30
+ rm = obj.read_marks.where(:user_id => user.id).first || obj.read_marks.build(:user_id => user.id)
31
+ rm.timestamp = timestamp
32
+ rm.save!
33
+ end
27
34
  end
28
35
  end
29
36
  end
@@ -44,7 +51,7 @@ module Unread
44
51
  def cleanup_read_marks!
45
52
  assert_reader_class
46
53
 
47
- ReadMark.reader_class.find_each do |user|
54
+ ReadMark.reader_scope.find_each do |user|
48
55
  ReadMark.transaction do
49
56
  if oldest_timestamp = read_scope(user).unread_by(user).minimum(readable_options[:on])
50
57
  # There are unread items, so update the global read_mark for this user to the oldest
@@ -91,12 +98,12 @@ module Unread
91
98
  def assert_reader(user)
92
99
  assert_reader_class
93
100
 
94
- raise ArgumentError, "Class #{user.class.name} is not registered by acts_as_reader!" unless user.is_a?(ReadMark.reader_class)
95
- raise ArgumentError, "The given user has no id!" unless user.id
101
+ raise ArgumentError, "Class #{user.class.name} is not registered by acts_as_reader." unless user.is_a?(ReadMark.reader_class)
102
+ raise ArgumentError, "The given user has no id." unless user.id
96
103
  end
97
104
 
98
105
  def assert_reader_class
99
- raise RuntimeError, 'There is no class using acts_as_reader!' unless ReadMark.reader_class
106
+ raise RuntimeError, 'There is no class using acts_as_reader.' unless ReadMark.reader_class
100
107
  end
101
108
  end
102
109
 
@@ -112,7 +119,7 @@ module Unread
112
119
  true
113
120
  end
114
121
  else
115
- !!self.class.unread_by(user).exists?(self) # Rails4 does not return true/false, but nil/count instead.
122
+ self.class.unread_by(user).exists?(self.id)
116
123
  end
117
124
  end
118
125
 
@@ -1,3 +1,3 @@
1
1
  module Unread
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
@@ -1,4 +1,8 @@
1
1
  class Reader < ActiveRecord::Base
2
2
  self.primary_key = 'number'
3
- acts_as_reader
3
+
4
+ scope :not_foo, -> { where('name <> "foo"') }
5
+ scope :not_bar, -> { where('name <> "bar"') }
6
+
7
+ acts_as_reader :scopes => [:not_foo, :not_bar]
4
8
  end
@@ -4,4 +4,8 @@ describe ReadMark do
4
4
  it "should have reader_class" do
5
5
  expect(ReadMark.reader_class).to eq Reader
6
6
  end
7
+
8
+ it "should have reader_scope" do
9
+ expect(ReadMark.reader_scope).to eq Reader.not_foo.not_bar
10
+ end
7
11
  end
@@ -132,6 +132,14 @@ describe Unread::Readable do
132
132
  expect(@email2.unread?(@reader)).to be_falsey
133
133
  end
134
134
 
135
+ it "should perform less queries if the objects are already read" do
136
+ Email.mark_as_read! :all, :for => @reader
137
+
138
+ expect {
139
+ Email.mark_as_read! [ @email1, @email2 ], :for => @reader
140
+ }.to perform_queries(1)
141
+ end
142
+
135
143
  it "should mark all objects as read" do
136
144
  Email.mark_as_read! :all, :for => @reader
137
145
 
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.0
4
+ version: 0.5.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: 2014-06-09 00:00:00.000000000 Z
11
+ date: 2015-03-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -127,6 +127,7 @@ files:
127
127
  - ci/Gemfile-rails-3-2
128
128
  - ci/Gemfile-rails-4-0
129
129
  - ci/Gemfile-rails-4-1
130
+ - ci/Gemfile-rails-4-2
130
131
  - lib/generators/unread/migration/migration_generator.rb
131
132
  - lib/generators/unread/migration/templates/migration.rb
132
133
  - lib/unread.rb
@@ -165,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
166
  version: '0'
166
167
  requirements: []
167
168
  rubyforge_project: unread
168
- rubygems_version: 2.2.2
169
+ rubygems_version: 2.4.6
169
170
  signing_key:
170
171
  specification_version: 4
171
172
  summary: Manages read/unread status of ActiveRecord objects