unread 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  rvm:
2
2
  - 1.8.7
3
- - 1.9.2
3
+ - 1.9.3
4
4
  gemfile:
5
5
  - ci/Gemfile.rails-2.3.x
6
6
  - ci/Gemfile.rails-3.0.x
data/README.md CHANGED
@@ -1,24 +1,25 @@
1
1
  Unread
2
2
  ======
3
3
 
4
- Gem to manage read/unread status of ActiveRecord objects - and it's fast.
4
+ Ruby gem to manage read/unread status of ActiveRecord objects - and it's fast.
5
5
 
6
6
  [![Build Status](https://secure.travis-ci.org/ledermann/unread.png)](http://travis-ci.org/ledermann/unread)
7
7
 
8
+
8
9
  ## Features
9
10
 
10
- * Manages unread records for anything you want your users to read (like messages, documents, comments etc.)
11
- * Supports "mark as read" to mark a **single** record as read
12
- * Supports "mark all as read" to mark **all** records as read in a single step
13
- * Gives you a named_scope to get the unread records for a given user
11
+ * Manages unread records for anything you want users to read (like messages, documents, comments etc.)
12
+ * Supports _mark as read_ to mark a **single** record as read
13
+ * Supports _mark all as read__ to mark **all** records as read in a single step
14
+ * Gives you a scope to get the unread records for a given user
14
15
  * Needs only one additional database table
15
16
  * Most important: Great performance
16
17
 
17
18
 
18
19
  ## Requirements
19
20
 
20
- * Ruby 1.8.7 or 1.9.2
21
- * ActiveRecord 2.3.x, 3.0.x, 3.1.x (tested with SQLite and MySQL)
21
+ * Ruby 1.8.7 or 1.9.x
22
+ * Rails 2.3.x, 3.0.x, 3.1.x (tested with SQLite and MySQL)
22
23
  * Needs a timestamp field in your models (e.g. created_at) with a database index on it
23
24
 
24
25
 
@@ -28,7 +29,7 @@ Step 1: Add this to your Gemfile:
28
29
 
29
30
  gem 'unread'
30
31
 
31
- and run
32
+ and run
32
33
 
33
34
  bundle
34
35
 
@@ -87,16 +88,16 @@ Step 2: Add this migration:
87
88
 
88
89
  ## How does it work?
89
90
 
90
- The main idea of this gem is to manage a list of read items for every user **after** a certain timestamp.
91
+ The main idea of this gem is to manage a list of read items for every reader **after** a certain timestamp.
91
92
 
92
- The gem defines a named_scope doing a LEFT JOIN to this list, so your app can get the unread items in a performant manner. Of course, other scopes can be combined.
93
+ The gem defines a scope doing a LEFT JOIN to this list, so your app can get the unread items in a performant manner. Of course, other scopes can be combined.
93
94
 
94
95
  It will be ensured that the list of read items will not grow up too much:
95
96
 
96
- * If a user uses "mark all as read", his list is deleted and the timestamp is set to the current time.
97
+ * If a user uses "mark all as read", his list gets deleted and the timestamp is set to the current time.
97
98
  * If a user never uses "mark all as read", the list will grow and grow with each item he reads. But there is help: Your app can use a cleanup method which removes unnecessary list items.
98
99
 
99
- Overall, this gem can be used for large tables, too. If you are in doubt, look at the generated SQL queries, here is an example:
100
+ Overall, this gem can be used for large data. Please have a look at the generated SQL queries, here is an example:
100
101
 
101
102
  # Assuming we have a user who has marked all messages as read on 2010-10-20 08:50
102
103
  current_user = User.find(42)
@@ -114,22 +115,17 @@ Overall, this gem can be used for large tables, too. If you are in doubt, look a
114
115
  # WHERE read_marks.id IS NULL
115
116
  # AND messages.created_at > '2010-10-20 08:50:00'
116
117
 
117
- Hint: You should add a database index on messages.created_at.
118
+ Hint: You should add a database index on `messages.created_at`.
118
119
 
119
120
 
120
121
  ## Similar tools
121
122
 
122
- There a two other gems/plugins doing a similar job:
123
+ There are two other gems/plugins doing a similar job:
123
124
 
124
125
  * http://github.com/jhnvz/mark_as_read
125
126
  * http://github.com/mbleigh/acts-as-readable
126
127
 
127
- 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.
128
-
129
-
130
- ## TODO
131
-
132
- * Add more documentation
128
+ 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.
133
129
 
134
130
 
135
131
  Copyright (c) 2010,2011 Georg Ledermann, released under the MIT license
@@ -1,6 +1,6 @@
1
1
  source :rubygems
2
2
 
3
- gem 'activerecord', '~> 3.1.0'
3
+ gem 'activerecord', '~> 3.1.1'
4
4
  gem 'sqlite3'
5
5
  gem 'mysql2', '>= 0.3.6'
6
6
  gem 'mocha'
@@ -1,5 +1,4 @@
1
1
  class ReadMark < ActiveRecord::Base
2
- belongs_to :user
3
2
  belongs_to :readable, :polymorphic => true
4
3
 
5
4
  validates_presence_of :user_id, :readable_type
@@ -11,10 +10,16 @@ class ReadMark < ActiveRecord::Base
11
10
  send scope_method, :readable_type, lambda { |readable_type | { :conditions => { :readable_type => readable_type }}}
12
11
  send scope_method, :user, lambda { |user| { :conditions => { :user_id => user.id }}}
13
12
  send scope_method, :older_than, lambda { |timestamp| { :conditions => [ 'timestamp < ?', timestamp] }}
13
+
14
+ # Returns the class defined by ActsAsReadable::acts_as_reader
15
+ def self.reader_class
16
+ user_association = reflect_on_all_associations(:belongs_to).find { |assoc| assoc.name == :user }
17
+ user_association.try(:klass)
18
+ end
14
19
 
15
20
  if respond_to?(:class_attribute)
16
- class_attribute :reader_class, :readable_classes
21
+ class_attribute :readable_classes
17
22
  else
18
- class_inheritable_accessor :reader_class, :readable_classes
23
+ class_inheritable_accessor :readable_classes
19
24
  end
20
25
  end
@@ -5,9 +5,9 @@ module Unread
5
5
 
6
6
  module ActsAsReadable
7
7
  def acts_as_reader
8
- ReadMark.reader_class = self
8
+ ReadMark.belongs_to :user, :class_name => self.to_s
9
9
 
10
- has_many :read_marks, :dependent => :delete_all
10
+ has_many :read_marks, :dependent => :delete_all, :foreign_key => 'user_id'
11
11
 
12
12
  after_create do |user|
13
13
  (ReadMark.readable_classes || []).each do |klass|
@@ -1,3 +1,3 @@
1
1
  module Unread
2
- VERSION = '0.0.5'
2
+ VERSION = '0.0.6'
3
3
  end
@@ -1,5 +1,5 @@
1
1
  ActiveRecord::Schema.define(:version => 0) do
2
- create_table :users, :force => true do |t|
2
+ create_table :readers, :force => true do |t|
3
3
  t.string :name
4
4
  end
5
5
 
@@ -15,7 +15,7 @@ ActiveRecord::Base.establish_connection(db_name)
15
15
  ActiveRecord::Migration.verbose = false
16
16
  load(File.dirname(__FILE__) + "/schema.rb")
17
17
 
18
- class User < ActiveRecord::Base
18
+ class Reader < ActiveRecord::Base
19
19
  acts_as_reader
20
20
  end
21
21
 
@@ -2,8 +2,8 @@ require 'test_helper'
2
2
 
3
3
  class UnreadTest < ActiveSupport::TestCase
4
4
  def setup
5
- @user = User.create! :name => 'David'
6
- @other_user = User.create :name => 'Matz'
5
+ @reader = Reader.create! :name => 'David'
6
+ @other_reader = Reader.create :name => 'Matz'
7
7
  wait
8
8
  @email1 = Email.create!
9
9
  wait
@@ -11,7 +11,7 @@ class UnreadTest < ActiveSupport::TestCase
11
11
  end
12
12
 
13
13
  def teardown
14
- User.delete_all
14
+ Reader.delete_all
15
15
  Email.delete_all
16
16
  ReadMark.delete_all
17
17
  end
@@ -25,15 +25,15 @@ class UnreadTest < ActiveSupport::TestCase
25
25
  end
26
26
 
27
27
  def test_reader_class
28
- assert_equal User, ReadMark.reader_class
28
+ assert_equal Reader, ReadMark.reader_class
29
29
  end
30
30
 
31
31
  def test_scope
32
- assert_equal [@email1, @email2], Email.unread_by(@user)
33
- assert_equal [@email1, @email2], Email.unread_by(@other_user)
32
+ assert_equal [@email1, @email2], Email.unread_by(@reader)
33
+ assert_equal [@email1, @email2], Email.unread_by(@other_reader)
34
34
 
35
- assert_equal 2, Email.unread_by(@user).count
36
- assert_equal 2, Email.unread_by(@other_user).count
35
+ assert_equal 2, Email.unread_by(@reader).count
36
+ assert_equal 2, Email.unread_by(@other_reader).count
37
37
 
38
38
  assert_raise(ArgumentError) {
39
39
  Email.unread_by(42)
@@ -41,15 +41,15 @@ class UnreadTest < ActiveSupport::TestCase
41
41
  end
42
42
 
43
43
  def test_scope_after_reset
44
- @email1.mark_as_read! :for => @user
44
+ @email1.mark_as_read! :for => @reader
45
45
 
46
- assert_equal [@email2], Email.unread_by(@user)
47
- assert_equal 1, Email.unread_by(@user).count
46
+ assert_equal [@email2], Email.unread_by(@reader)
47
+ assert_equal 1, Email.unread_by(@reader).count
48
48
  end
49
49
 
50
50
  def test_unread_after_create
51
- assert_equal true, @email1.unread?(@user)
52
- assert_equal true, @email1.unread?(@other_user)
51
+ assert_equal true, @email1.unread?(@reader)
52
+ assert_equal true, @email1.unread?(@other_reader)
53
53
 
54
54
  assert_raise(ArgumentError) {
55
55
  @email1.unread?(42)
@@ -57,77 +57,77 @@ class UnreadTest < ActiveSupport::TestCase
57
57
  end
58
58
 
59
59
  def test_unread_after_update
60
- @email1.mark_as_read! :for => @user
60
+ @email1.mark_as_read! :for => @reader
61
61
  wait
62
62
  @email1.update_attributes! :subject => 'changed'
63
63
 
64
- assert_equal true, @email1.unread?(@user)
64
+ assert_equal true, @email1.unread?(@reader)
65
65
  end
66
66
 
67
67
  def test_mark_as_read
68
- @email1.mark_as_read! :for => @user
68
+ @email1.mark_as_read! :for => @reader
69
69
 
70
- assert_equal false, @email1.unread?(@user)
71
- assert_equal [@email2], Email.unread_by(@user)
70
+ assert_equal false, @email1.unread?(@reader)
71
+ assert_equal [@email2], Email.unread_by(@reader)
72
72
 
73
- assert_equal true, @email1.unread?(@other_user)
74
- assert_equal [@email1, @email2], Email.unread_by(@other_user)
73
+ assert_equal true, @email1.unread?(@other_reader)
74
+ assert_equal [@email1, @email2], Email.unread_by(@other_reader)
75
75
 
76
- assert_equal 1, @user.read_marks.single.count
77
- assert_equal @email1, @user.read_marks.single.first.readable
76
+ assert_equal 1, @reader.read_marks.single.count
77
+ assert_equal @email1, @reader.read_marks.single.first.readable
78
78
  end
79
79
 
80
80
  def test_mark_as_read_multiple
81
- assert_equal true, @email1.unread?(@user)
82
- assert_equal true, @email2.unread?(@user)
81
+ assert_equal true, @email1.unread?(@reader)
82
+ assert_equal true, @email2.unread?(@reader)
83
83
 
84
- Email.mark_as_read! [ @email1, @email2 ], :for => @user
84
+ Email.mark_as_read! [ @email1, @email2 ], :for => @reader
85
85
 
86
- assert_equal false, @email1.unread?(@user)
87
- assert_equal false, @email2.unread?(@user)
86
+ assert_equal false, @email1.unread?(@reader)
87
+ assert_equal false, @email2.unread?(@reader)
88
88
  end
89
89
 
90
90
  def test_mark_as_read_with_marked_all
91
91
  wait
92
92
 
93
- Email.mark_as_read! :all, :for => @user
94
- @email1.mark_as_read! :for => @user
93
+ Email.mark_as_read! :all, :for => @reader
94
+ @email1.mark_as_read! :for => @reader
95
95
 
96
- assert_equal [], @user.read_marks.single
96
+ assert_equal [], @reader.read_marks.single
97
97
  end
98
98
 
99
99
  def test_mark_as_read_twice
100
- @email1.mark_as_read! :for => @user
101
- @email1.mark_as_read! :for => @user
100
+ @email1.mark_as_read! :for => @reader
101
+ @email1.mark_as_read! :for => @reader
102
102
 
103
- assert_equal 1, @user.read_marks.single.count
103
+ assert_equal 1, @reader.read_marks.single.count
104
104
  end
105
105
 
106
106
  def test_mark_all_as_read
107
- Email.mark_as_read! :all, :for => @user
108
- assert_equal Time.now.to_s, Email.read_mark(@user).timestamp.to_s
107
+ Email.mark_as_read! :all, :for => @reader
108
+ assert_equal Time.now.to_s, Email.read_mark(@reader).timestamp.to_s
109
109
 
110
- assert_equal [], @user.read_marks.single
110
+ assert_equal [], @reader.read_marks.single
111
111
  assert_equal 0, ReadMark.single.count
112
112
  assert_equal 2, ReadMark.global.count
113
113
  end
114
114
 
115
115
  def test_cleanup_read_marks
116
- assert_equal 0, @user.read_marks.single.count
116
+ assert_equal 0, @reader.read_marks.single.count
117
117
 
118
- @email1.mark_as_read! :for => @user
118
+ @email1.mark_as_read! :for => @reader
119
119
 
120
- assert_equal [@email2], Email.unread_by(@user)
121
- assert_equal 1, @user.read_marks.single.count
120
+ assert_equal [@email2], Email.unread_by(@reader)
121
+ assert_equal 1, @reader.read_marks.single.count
122
122
 
123
123
  Email.cleanup_read_marks!
124
124
 
125
- @user.reload
126
- assert_equal 0, @user.read_marks.single.count
125
+ @reader.reload
126
+ assert_equal 0, @reader.read_marks.single.count
127
127
  end
128
128
 
129
129
  def test_cleanup_read_marks_not_delete_from_other_readables
130
- other_read_mark = @user.read_marks.create! :readable_type => 'Foo', :readable_id => 42, :timestamp => 5.years.ago
130
+ other_read_mark = @reader.read_marks.create! :readable_type => 'Foo', :readable_id => 42, :timestamp => 5.years.ago
131
131
  Email.cleanup_read_marks!
132
132
  assert_equal true, ReadMark.exists?(other_read_mark.id)
133
133
  end
@@ -1,7 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
3
  require "unread/version"
4
- require 'active_record/version'
5
4
 
6
5
  Gem::Specification.new do |s|
7
6
  s.name = "unread"
@@ -24,10 +23,5 @@ Gem::Specification.new do |s|
24
23
  s.add_development_dependency 'rake'
25
24
  s.add_development_dependency 'mocha'
26
25
  s.add_development_dependency 'sqlite3'
27
-
28
- if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR >= 1
29
- s.add_development_dependency 'mysql2', '>= 0.3.6'
30
- else
31
- s.add_development_dependency 'mysql2', '~> 0.2.11'
32
- end
26
+ s.add_development_dependency 'mysql2'
33
27
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: unread
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 5
10
- version: 0.0.5
9
+ - 6
10
+ version: 0.0.6
11
11
  platform: ruby
12
12
  authors:
13
13
  - Georg Ledermann
@@ -15,7 +15,8 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-09 00:00:00 Z
18
+ date: 2011-11-11 00:00:00 +01:00
19
+ default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: activerecord
@@ -82,12 +83,10 @@ dependencies:
82
83
  requirements:
83
84
  - - ">="
84
85
  - !ruby/object:Gem::Version
85
- hash: 31
86
+ hash: 3
86
87
  segments:
87
88
  - 0
88
- - 3
89
- - 6
90
- version: 0.3.6
89
+ version: "0"
91
90
  type: :development
92
91
  version_requirements: *id005
93
92
  description: "This gem creates a scope for unread objects and adds methods to mark objects as read "
@@ -121,6 +120,7 @@ files:
121
120
  - test/unread_test.rb
122
121
  - uninstall.rb
123
122
  - unread.gemspec
123
+ has_rdoc: true
124
124
  homepage: ""
125
125
  licenses: []
126
126
 
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
150
  requirements: []
151
151
 
152
152
  rubyforge_project: unread
153
- rubygems_version: 1.8.6
153
+ rubygems_version: 1.6.2
154
154
  signing_key:
155
155
  specification_version: 3
156
156
  summary: Manages read/unread status of ActiveRecord objects