module Unread::Readable::ClassMethods
Public Instance Methods
assert_reader(reader)
click to toggle source
# File lib/unread/readable.rb, line 100 def assert_reader(reader) assert_reader_class raise ArgumentError, "Class #{reader.class.name} is not registered by acts_as_reader." unless ReadMark.reader_classes.any? { |klass| reader.is_a?(klass) } raise ArgumentError, "The given reader has no id." unless reader.id end
assert_reader_class()
click to toggle source
# File lib/unread/readable.rb, line 107 def assert_reader_class raise RuntimeError, 'There is no class using acts_as_reader.' unless ReadMark.reader_classes end
cleanup_read_marks!()
click to toggle source
# File lib/unread/readable.rb, line 81 def cleanup_read_marks! assert_reader_class Unread::GarbageCollector.new(self).run! end
mark_as_read!(target, options)
click to toggle source
# File lib/unread/readable.rb, line 4 def mark_as_read!(target, options) raise ArgumentError unless options.is_a?(Hash) reader = options[:for] assert_reader(reader) if target == :all reset_read_marks_for_user(reader) elsif target.respond_to?(:each) mark_collection_as_read(target, reader) else raise ArgumentError end end
mark_collection_as_read(collection, reader)
click to toggle source
# File lib/unread/readable.rb, line 19 def mark_collection_as_read(collection, reader) ReadMark.transaction do global_timestamp = reader.read_mark_global(self).try(:timestamp) collection.each do |obj| raise ArgumentError unless obj.is_a?(self) timestamp = obj.send(readable_options[:on]) if global_timestamp && global_timestamp >= timestamp # The object is implicitly marked as read, so there is nothing to do else mark_collection_item_as_read(obj, reader, timestamp) end end end end
mark_collection_item_as_read(obj, reader, timestamp)
click to toggle source
# File lib/unread/readable.rb, line 36 def mark_collection_item_as_read(obj, reader, timestamp) marking_proc = proc { rm = obj.read_marks.find_or_initialize_by(reader: reader) rm.timestamp = timestamp rm.save! } if using_postgresql? # With PostgreSQL, a transaction is unusable after a unique constraint vialoation. # To avoid this, nested transactions are required. # http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html#module-ActiveRecord::Transactions::ClassMethods-label-Exception+handling+and+rolling+back ReadMark.transaction(requires_new: true) do begin marking_proc.call rescue ActiveRecord::RecordNotUnique # The object is explicitly marked as read, so rollback the inner transaction raise ActiveRecord::Rollback end end else begin marking_proc.call rescue ActiveRecord::RecordNotUnique # The object is explicitly marked as read, so there is nothing to do end end end
read_scope(reader)
click to toggle source
A scope with all items accessable for the given reader It's used in cleanup_read_marks! to support a filtered cleanup Should be overriden if a reader doesn't have access to all items Default: reader has access to all items and should read them all
Example:
def Message.read_scope(reader) reader.visible_messages end
# File lib/unread/readable.rb, line 73 def read_scope(reader) self end
readable_parent()
click to toggle source
# File lib/unread/readable.rb, line 77 def readable_parent self.ancestors.find { |ancestor| ReadMark.readable_classes.include?(ancestor) } end
reset_read_marks_for_user(reader)
click to toggle source
# File lib/unread/readable.rb, line 86 def reset_read_marks_for_user(reader) assert_reader(reader) ReadMark.transaction do reader.read_marks.where(readable_type: self.readable_parent.name).delete_all rm = reader.read_marks.new rm.readable_type = self.readable_parent.name rm.timestamp = Time.current rm.save! end reader.forget_memoized_read_mark_global end