acts-as-messageable 0.1.0 → 0.2.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.
- data/Gemfile +11 -0
- data/README.rdoc +22 -64
- data/Rakefile +41 -19
- data/VERSION +1 -1
- data/acts-as-messageable.gemspec +67 -0
- data/lib/acts-as-messageable.rb +7 -7
- data/lib/acts-as-messageable/acts-as-messageable.rb +74 -0
- data/lib/acts-as-messageable/message.rb +74 -0
- data/lib/acts-as-messageable/relation.rb +12 -0
- data/lib/generators/{acts_as_messageable → acts-as-messageable}/migration/migration_generator.rb +5 -10
- data/lib/generators/{acts_as_messageable → acts-as-messageable}/migration/templates/migration.rb +4 -4
- data/rails/init.rb +1 -1
- data/spec/acts-as-messageable_spec.rb +61 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/support/user.rb +3 -0
- metadata +99 -44
- data/lib/acts_as_messageable/acts-as-messageable.rb +0 -94
- data/lib/acts_as_messageable/message.rb +0 -59
- data/test/message_test.rb +0 -114
data/Gemfile
ADDED
data/README.rdoc
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
= ActsAsMessageable
|
2
3
|
The Acts As Messageable allows communication between the models.
|
3
4
|
|
@@ -8,87 +9,44 @@ To use it, add it to your Gemfile:
|
|
8
9
|
|
9
10
|
== Post instalation
|
10
11
|
|
11
|
-
|
12
|
-
|
12
|
+
rails g acts_as_messageable:migration [table_name] # default 'messages'
|
13
|
+
rake db:migrate
|
13
14
|
|
14
15
|
== Usage
|
15
16
|
|
16
17
|
class User < ActiveRecord::Base
|
17
|
-
acts_as_messageable
|
18
|
+
acts_as_messageable :table_name => "table_with_messages", # default 'messages'
|
19
|
+
:required => :body # default [:topic, :body]
|
18
20
|
end
|
19
21
|
|
20
22
|
== Send message
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
@user1.send_message(@user2, "Message to user2", "Hi user 2!;-)")
|
25
|
-
@user2.send_message(@user1, "Re: Message to user2", "Hi there!:)")
|
26
|
-
|
27
|
-
== Inbox/Outbox
|
28
|
-
|
29
|
-
# Show inbox
|
30
|
-
@user.received
|
31
|
-
# Show inbox trash
|
32
|
-
@user.received(:deleted => true)
|
33
|
-
# Show inbox with inbox trash
|
34
|
-
@user.received(:all => true)
|
35
|
-
|
36
|
-
# Show outbox
|
37
|
-
@user.sent
|
38
|
-
# Show outbox trash
|
39
|
-
@user.sent(:deleted => true)
|
40
|
-
# Show outbox with inbox trash
|
41
|
-
@user.sent(:all => true)
|
42
|
-
|
43
|
-
# Show trash
|
44
|
-
@user.messages(:deleted => true)
|
45
|
-
# Show all messages
|
46
|
-
@user.messages(:all => true)
|
24
|
+
@alice = User.first
|
25
|
+
@bob = User.last
|
47
26
|
|
48
|
-
|
27
|
+
@alice.send_message(@bob, "Message topic", "Hi bob!")
|
28
|
+
@bob.send_message(@alice, "Re: Message topic", "Hi alice!")
|
49
29
|
|
50
|
-
|
51
|
-
@
|
52
|
-
|
53
|
-
end
|
30
|
+
== New API
|
31
|
+
@alice.messages -- all messages connected with @alice (inbox/outbox)
|
32
|
+
@alice.deleted_messages -- all messages connected with @alice (trash)
|
54
33
|
|
55
|
-
@
|
56
|
-
|
57
|
-
|
34
|
+
@alice.messages.are_from(@bob) -- all message form @bob
|
35
|
+
@alice.messages.are_to(@bob) -- all message to @bob
|
36
|
+
@alice.messages.id(@id_of_message) -- message with id id_of_message
|
37
|
+
@alice.messages.readed -- all readed @alice messages
|
38
|
+
@alice.messages.unaded -- all unreaded @alice messages
|
58
39
|
|
59
|
-
|
60
|
-
message.delete
|
61
|
-
end
|
40
|
+
You can use multiple filters at the same time
|
62
41
|
|
63
|
-
@
|
64
|
-
|
65
|
-
end
|
42
|
+
@alice.messages.are_from(@bob).are_to(@alice).readed -- all message from @bob to @alice and readed
|
43
|
+
@alice.deleted_message.are_from(@bob) -- all deleted messages from @bob
|
66
44
|
|
67
|
-
|
68
|
-
messsage.delete
|
69
|
-
end
|
45
|
+
=== Delete message
|
70
46
|
|
71
|
-
@
|
47
|
+
@alice.messages.process do |message|
|
72
48
|
message.delete
|
73
49
|
end
|
74
50
|
|
75
51
|
|
76
|
-
# Delete by hand
|
77
|
-
@user.delete_message(@user.messages(:id => 10))
|
78
|
-
|
79
|
-
== Search
|
80
|
-
|
81
|
-
# Search message
|
82
|
-
@user.messages # all messages (in and out)
|
83
|
-
@user.messages(:from => @user2) # all messages from @user2
|
84
|
-
@user.messages(:to => @user2) # all messages to @user2
|
85
|
-
@user.messages(:id => 2) # message where message.id = 2
|
86
|
-
|
87
|
-
== Blocks time ;-)
|
88
|
-
|
89
|
-
@user.messages do |messsage|
|
90
|
-
# message stuff...
|
91
|
-
end
|
92
|
-
|
93
52
|
Copyright © 2011 Piotr Niełacny (http://ruby-blog.pl), released under the MIT license
|
94
|
-
|
data/Rakefile
CHANGED
@@ -1,24 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
1
12
|
require 'rake'
|
2
|
-
require 'rake/testtask'
|
3
13
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
gem.name = "acts-as-messageable"
|
17
|
+
gem.email = "piotr.nielacny@gmail.com"
|
18
|
+
gem.summary = "Make user messageable!;-)"
|
19
|
+
gem.homepage = "http://github.com/LTe/acts_as_messageable"
|
20
|
+
gem.authors = ["Piotr Nielacny"]
|
21
|
+
# dependencies defined in Gemfile
|
9
22
|
end
|
23
|
+
Jeweler::RubygemsDotOrgTasks.new
|
10
24
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
require 'rspec/core'
|
26
|
+
require 'rspec/core/rake_task'
|
27
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
28
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
32
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
33
|
+
spec.rcov = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "acts-as-messageable #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
24
46
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{acts-as-messageable}
|
8
|
+
s.version = "0.2.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Piotr Nielacny"]
|
12
|
+
s.date = %q{2011-05-04}
|
13
|
+
s.email = %q{piotr.nielacny@gmail.com}
|
14
|
+
s.extra_rdoc_files = [
|
15
|
+
"README.rdoc"
|
16
|
+
]
|
17
|
+
s.files = [
|
18
|
+
"Gemfile",
|
19
|
+
"MIT-LICENSE",
|
20
|
+
"README.rdoc",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"acts-as-messageable.gemspec",
|
24
|
+
"lib/acts-as-messageable.rb",
|
25
|
+
"lib/acts-as-messageable/acts-as-messageable.rb",
|
26
|
+
"lib/acts-as-messageable/message.rb",
|
27
|
+
"lib/acts-as-messageable/relation.rb",
|
28
|
+
"lib/generators/acts-as-messageable/migration/migration_generator.rb",
|
29
|
+
"lib/generators/acts-as-messageable/migration/templates/migration.rb",
|
30
|
+
"rails/init.rb",
|
31
|
+
"spec/acts-as-messageable_spec.rb",
|
32
|
+
"spec/spec_helper.rb",
|
33
|
+
"spec/support/user.rb"
|
34
|
+
]
|
35
|
+
s.homepage = %q{http://github.com/LTe/acts_as_messageable}
|
36
|
+
s.require_paths = ["lib"]
|
37
|
+
s.rubygems_version = %q{1.6.2}
|
38
|
+
s.summary = %q{Make user messageable!;-)}
|
39
|
+
|
40
|
+
if s.respond_to? :specification_version then
|
41
|
+
s.specification_version = 3
|
42
|
+
|
43
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
44
|
+
s.add_runtime_dependency(%q<activerecord>, ["~> 3.0.0"])
|
45
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
|
46
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
47
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
|
48
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
49
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
52
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
53
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
54
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
55
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
56
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
57
|
+
end
|
58
|
+
else
|
59
|
+
s.add_dependency(%q<activerecord>, ["~> 3.0.0"])
|
60
|
+
s.add_dependency(%q<rspec>, ["~> 2.3.0"])
|
61
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
62
|
+
s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
|
63
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
64
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
data/lib/acts-as-messageable.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
require "active_record"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
require 'acts_as_messageable/acts-as-messageable'
|
6
|
-
require 'acts_as_messageable/message'
|
7
|
-
|
8
|
-
$LOAD_PATH.shift
|
2
|
+
require 'acts-as-messageable/acts-as-messageable'
|
3
|
+
require 'acts-as-messageable/message'
|
4
|
+
require 'acts-as-messageable/relation'
|
9
5
|
|
10
6
|
if defined?(ActiveRecord::Base)
|
11
7
|
ActiveRecord::Base.send :include, ActsAsMessageable::Model
|
12
8
|
end
|
9
|
+
|
10
|
+
if defined?(ActiveRecord::Relation)
|
11
|
+
ActiveRecord::Relation.send :include, ActsAsMessageable::Relation
|
12
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ActsAsMessageable
|
2
|
+
module Model
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
# Method make ActiveRecord::Base object messageable
|
10
|
+
# @param [Symbol] :table_name - table name for messages
|
11
|
+
def acts_as_messageable(options = {})
|
12
|
+
class_eval do
|
13
|
+
has_many :received_messages,
|
14
|
+
:as => :received_messageable,
|
15
|
+
:class_name => "ActsAsMessageable::Message",
|
16
|
+
:dependent => :nullify
|
17
|
+
has_many :sent_messages,
|
18
|
+
:as => :sent_messageable,
|
19
|
+
:class_name => "ActsAsMessageable::Message",
|
20
|
+
:dependent => :nullify
|
21
|
+
end
|
22
|
+
|
23
|
+
table_name = %q{set_table_name "#{options[:table_name] || "messages"}"}
|
24
|
+
ActsAsMessageable::Message.class_eval(table_name)
|
25
|
+
|
26
|
+
validation = %q{validates_presence_of options[:required] || [:topic ,:body]}
|
27
|
+
ActsAsMessageable::Message.class_eval(validation)
|
28
|
+
|
29
|
+
include ActsAsMessageable::Model::InstanceMethods
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
module InstanceMethods
|
35
|
+
# Get all messages connected with user
|
36
|
+
# @return [ActiveRecord::Relation] all messages connected with user
|
37
|
+
def messages(trash = false)
|
38
|
+
result = ActsAsMessageable::Message.connected_with(self, trash)
|
39
|
+
result.relation_context = self
|
40
|
+
|
41
|
+
result
|
42
|
+
end
|
43
|
+
|
44
|
+
def deleted_messages
|
45
|
+
messages true
|
46
|
+
end
|
47
|
+
|
48
|
+
# Method sens message to another user
|
49
|
+
# @param [ActiveRecord::Base] to
|
50
|
+
# @param [String] topic
|
51
|
+
# @param [String] body
|
52
|
+
#
|
53
|
+
# @return [ActsAsMessageable::Message] the message object
|
54
|
+
def send_message(to, topic, body)
|
55
|
+
@message = ActsAsMessageable::Message.create!(:topic => topic, :body => body)
|
56
|
+
|
57
|
+
self.sent_messages << @message
|
58
|
+
to.received_messages << @message
|
59
|
+
end
|
60
|
+
|
61
|
+
def delete_message(message)
|
62
|
+
current_user = self
|
63
|
+
|
64
|
+
if message.received_messageable == current_user
|
65
|
+
message.update_attributes!(:recipient_delete => true)
|
66
|
+
elsif message.sent_messageable == current_user
|
67
|
+
message.update_attributes!(:sender_delete => true)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
module ActsAsMessageable
|
2
|
+
class Message < ::ActiveRecord::Base
|
3
|
+
belongs_to :received_messageable, :polymorphic => true
|
4
|
+
belongs_to :sent_messageable, :polymorphic => true
|
5
|
+
|
6
|
+
attr_accessible :topic,
|
7
|
+
:body,
|
8
|
+
:received_messageable_type,
|
9
|
+
:received_messageable_id,
|
10
|
+
:sent_messageable_type,
|
11
|
+
:sent_messageable_id,
|
12
|
+
:opened,
|
13
|
+
:recipient_delete,
|
14
|
+
:sender_delete
|
15
|
+
|
16
|
+
attr_accessor :context, :removed
|
17
|
+
|
18
|
+
# Sample documentation for scope
|
19
|
+
scope :are_from, lambda { |*args| where("sent_messageable_id = :sender", :sender => args.first) }
|
20
|
+
scope :are_to, lambda { |*args| where("received_messageable_id = :receiver", :receiver => args.first) }
|
21
|
+
scope :id, lambda { |*args| where("id = :id", :id => args.first) }
|
22
|
+
|
23
|
+
scope :connected_with, lambda { |*args| where("(sent_messageable_type = :sent_type and
|
24
|
+
sent_messageable_id = :sent_id and
|
25
|
+
sender_delete = :s_delete) or
|
26
|
+
(received_messageable_type = :received_type and
|
27
|
+
received_messageable_id = :received_id and
|
28
|
+
recipient_delete = :r_delete)",
|
29
|
+
:sent_type => args.first.class.name,
|
30
|
+
:sent_id => args.first.id,
|
31
|
+
:received_type => args.first.class.name,
|
32
|
+
:received_id => args.first.id,
|
33
|
+
:r_delete => args.last,
|
34
|
+
:s_delete => args.last)
|
35
|
+
}
|
36
|
+
scope :readed, lambda { where("opened = :opened", :opened => true) }
|
37
|
+
scope :unread, lambda { where("opened = :opened", :opened => false) }
|
38
|
+
scope :deleted, lambda { where("recipient_delete = :r_delete AND sender_delete = :s_delete",
|
39
|
+
:r_delete => true, :s_delete => true)}
|
40
|
+
|
41
|
+
def open?
|
42
|
+
self.opened?
|
43
|
+
end
|
44
|
+
|
45
|
+
def open
|
46
|
+
update_attributes!(:opened => true)
|
47
|
+
end
|
48
|
+
|
49
|
+
def mark_as_read
|
50
|
+
open
|
51
|
+
end
|
52
|
+
|
53
|
+
def close
|
54
|
+
update_attributes!(:opened => false)
|
55
|
+
end
|
56
|
+
|
57
|
+
def mark_as_unread
|
58
|
+
close
|
59
|
+
end
|
60
|
+
|
61
|
+
def from
|
62
|
+
sent_messageable
|
63
|
+
end
|
64
|
+
|
65
|
+
def to
|
66
|
+
received_messageable
|
67
|
+
end
|
68
|
+
|
69
|
+
def delete
|
70
|
+
self.removed = true
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module ActsAsMessageable
|
2
|
+
module Relation
|
3
|
+
attr_accessor :relation_context
|
4
|
+
|
5
|
+
def process(context = self.relation_context, &block)
|
6
|
+
self.each do |message|
|
7
|
+
block.call(message) if block_given?
|
8
|
+
context.delete_message(message) if message.removed
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/generators/{acts_as_messageable → acts-as-messageable}/migration/migration_generator.rb
RENAMED
@@ -1,25 +1,20 @@
|
|
1
1
|
require 'rails/generators/migration'
|
2
|
+
require 'rails/generators/active_record'
|
2
3
|
|
3
4
|
module ActsAsMessageable
|
4
5
|
class MigrationGenerator < Rails::Generators::Base
|
5
6
|
include Rails::Generators::Migration
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
end
|
8
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
9
|
+
argument :table_name, :type => :string, :default => "messages"
|
10
10
|
|
11
11
|
def self.next_migration_number(dirname)
|
12
|
-
|
13
|
-
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
14
|
-
else
|
15
|
-
"%.3d" % (current_migration_number(dirname) + 1)
|
16
|
-
end
|
12
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
17
13
|
end
|
18
14
|
|
19
15
|
def create_migration_file
|
20
16
|
migration_template 'migration.rb', 'db/migrate/create_messages_table.rb'
|
21
17
|
end
|
22
18
|
|
23
|
-
|
24
19
|
end
|
25
|
-
end
|
20
|
+
end
|
data/lib/generators/{acts_as_messageable → acts-as-messageable}/migration/templates/migration.rb
RENAMED
@@ -1,6 +1,6 @@
|
|
1
1
|
class CreateMessagesTable < ActiveRecord::Migration
|
2
2
|
def self.up
|
3
|
-
create_table
|
3
|
+
create_table :<%= table_name %> do |t|
|
4
4
|
t.string :topic
|
5
5
|
t.text :body
|
6
6
|
t.references :received_messageable, :polymorphic => true
|
@@ -11,10 +11,10 @@ class CreateMessagesTable < ActiveRecord::Migration
|
|
11
11
|
t.boolean :sender_delete, :default => false
|
12
12
|
end
|
13
13
|
|
14
|
-
add_index
|
14
|
+
add_index :<%= table_name %>, [:sent_messageable_id, :received_messageable_id], :name => "acts_as_messageable_ids"
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.down
|
18
|
-
drop_table
|
18
|
+
drop_table :<%= table_name %>
|
19
19
|
end
|
20
|
-
end
|
20
|
+
end
|
data/rails/init.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require '
|
1
|
+
require 'acts-as-messageable'
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe "ActsAsMessageable" do
|
4
|
+
it "should be two users in database" do
|
5
|
+
User.count.should == 2
|
6
|
+
end
|
7
|
+
|
8
|
+
it "alice should have one message from bob" do
|
9
|
+
@bob.send_message(@alice, "Topic", "Message body")
|
10
|
+
@alice.messages.count.should == 1
|
11
|
+
@alice.messages.are_from(@bob).count.should == 1
|
12
|
+
end
|
13
|
+
|
14
|
+
it "bob should have one message to alice in outbox" do
|
15
|
+
@bob.send_message(@alice, "Topic", "Message body")
|
16
|
+
@bob.messages.count.should == 1
|
17
|
+
@bob.messages.are_to(@alice).count.should == 1
|
18
|
+
end
|
19
|
+
|
20
|
+
it "bob should have one open message from alice" do
|
21
|
+
@alice.send_message(@bob, "Topic", "Message body")
|
22
|
+
@bob.messages.are_from(@alice).process do |m|
|
23
|
+
m.open
|
24
|
+
end
|
25
|
+
|
26
|
+
@bob.messages.readed.count.should == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it "bob should have one deleted message from alice" do
|
30
|
+
@alice.send_message(@bob, "Topic", "Message body")
|
31
|
+
@bob.messages.process do |m|
|
32
|
+
m.delete
|
33
|
+
end
|
34
|
+
|
35
|
+
@bob.messages.each do |m|
|
36
|
+
m.recipient_delete.should == true
|
37
|
+
m.sender_delete.should == false
|
38
|
+
end
|
39
|
+
|
40
|
+
@bob.deleted_messages.count.should == 1
|
41
|
+
@bob.messages.count.should == 0
|
42
|
+
end
|
43
|
+
|
44
|
+
it "alice should have one unread message from bob" do
|
45
|
+
@bob.send_message(@alice, "Topic", "Message body")
|
46
|
+
@alice.messages.are_from(@bob).unread.count.should == 1
|
47
|
+
@alice.messages.are_from(@bob).readed.count.should == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be in database message with id ..." do
|
51
|
+
message_id = @bob.send_message(@alice, "Topic", "Message body").first.id
|
52
|
+
@bob.messages.id(message_id).count.should == 1
|
53
|
+
end
|
54
|
+
|
55
|
+
it "message should have proper topic" do
|
56
|
+
@bob.send_message(@alice, "Topic", "Message body")
|
57
|
+
@bob.messages.count.should == 1
|
58
|
+
@bob.messages.first.topic == "Topic"
|
59
|
+
@bob.messages.first.body == "Message body"
|
60
|
+
end
|
61
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'acts-as-messageable'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.before(:all) do
|
12
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
13
|
+
create_database
|
14
|
+
|
15
|
+
@alice = User.create :email => "alice@example.com"
|
16
|
+
@bob = User.create :email => "bob@example.com"
|
17
|
+
end
|
18
|
+
|
19
|
+
config.after(:all) do
|
20
|
+
drop_database
|
21
|
+
end
|
22
|
+
|
23
|
+
config.after(:each) do
|
24
|
+
ActsAsMessageable::Message.destroy_all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_database
|
29
|
+
ActiveRecord::Schema.define(:version => 1) do
|
30
|
+
create_table :messages do |t|
|
31
|
+
t.string :topic
|
32
|
+
t.text :body
|
33
|
+
t.references :received_messageable, :polymorphic => true
|
34
|
+
t.references :sent_messageable, :polymorphic => true
|
35
|
+
t.boolean :opened, :default => false
|
36
|
+
t.boolean :opened, :default => false
|
37
|
+
t.boolean :recipient_delete, :default => false
|
38
|
+
t.boolean :sender_delete, :default => false
|
39
|
+
end
|
40
|
+
|
41
|
+
create_table :users do |t|
|
42
|
+
t.string :email
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def drop_database
|
48
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
49
|
+
ActiveRecord::Base.connection.drop_table(table)
|
50
|
+
end
|
51
|
+
end
|
metadata
CHANGED
@@ -1,77 +1,132 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts-as-messageable
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 1
|
9
|
-
- 0
|
10
|
-
version: 0.1.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Piotr Nielacny
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2011-02-17 00:00:00 +01:00
|
12
|
+
date: 2011-05-04 00:00:00.000000000 +02:00
|
19
13
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
requirement: &21323640 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *21323640
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: &21321880 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.3.0
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *21321880
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: bundler
|
39
|
+
requirement: &21318760 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 1.0.0
|
45
|
+
type: :development
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *21318760
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: jeweler
|
50
|
+
requirement: &21317420 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 1.6.0
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *21317420
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: rcov
|
61
|
+
requirement: &21316360 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *21316360
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: sqlite3-ruby
|
72
|
+
requirement: &21314120 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *21314120
|
22
81
|
description:
|
23
82
|
email: piotr.nielacny@gmail.com
|
24
83
|
executables: []
|
25
|
-
|
26
84
|
extensions: []
|
27
|
-
|
28
|
-
extra_rdoc_files:
|
85
|
+
extra_rdoc_files:
|
29
86
|
- README.rdoc
|
30
|
-
files:
|
87
|
+
files:
|
88
|
+
- Gemfile
|
31
89
|
- MIT-LICENSE
|
32
90
|
- README.rdoc
|
33
91
|
- Rakefile
|
34
92
|
- VERSION
|
93
|
+
- acts-as-messageable.gemspec
|
35
94
|
- lib/acts-as-messageable.rb
|
36
|
-
- lib/
|
37
|
-
- lib/
|
38
|
-
- lib/
|
39
|
-
- lib/generators/
|
95
|
+
- lib/acts-as-messageable/acts-as-messageable.rb
|
96
|
+
- lib/acts-as-messageable/message.rb
|
97
|
+
- lib/acts-as-messageable/relation.rb
|
98
|
+
- lib/generators/acts-as-messageable/migration/migration_generator.rb
|
99
|
+
- lib/generators/acts-as-messageable/migration/templates/migration.rb
|
40
100
|
- rails/init.rb
|
41
|
-
-
|
101
|
+
- spec/acts-as-messageable_spec.rb
|
102
|
+
- spec/spec_helper.rb
|
103
|
+
- spec/support/user.rb
|
42
104
|
has_rdoc: true
|
43
105
|
homepage: http://github.com/LTe/acts_as_messageable
|
44
106
|
licenses: []
|
45
|
-
|
46
107
|
post_install_message:
|
47
108
|
rdoc_options: []
|
48
|
-
|
49
|
-
require_paths:
|
109
|
+
require_paths:
|
50
110
|
- lib
|
51
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
112
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
segments:
|
113
|
+
requirements:
|
114
|
+
- - ! '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
segments:
|
58
118
|
- 0
|
59
|
-
|
60
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
119
|
+
hash: 4567414755196272734
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
121
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
66
|
-
segments:
|
67
|
-
- 0
|
68
|
-
version: "0"
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
69
126
|
requirements: []
|
70
|
-
|
71
127
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.
|
128
|
+
rubygems_version: 1.6.2
|
73
129
|
signing_key:
|
74
130
|
specification_version: 3
|
75
131
|
summary: Make user messageable!;-)
|
76
|
-
test_files:
|
77
|
-
- test/message_test.rb
|
132
|
+
test_files: []
|
@@ -1,94 +0,0 @@
|
|
1
|
-
module ActsAsMessageable
|
2
|
-
module Model
|
3
|
-
|
4
|
-
def self.included(base)
|
5
|
-
base.extend ClassMethods
|
6
|
-
end
|
7
|
-
|
8
|
-
module ClassMethods
|
9
|
-
def acts_as_messageable
|
10
|
-
class_eval do
|
11
|
-
has_many :received_messages, :as => :received_messageable, :class_name => "ActsAsMessageable::Message"
|
12
|
-
has_many :sent_messages, :as => :sent_messageable, :class_name => "ActsAsMessageable::Message"
|
13
|
-
end
|
14
|
-
|
15
|
-
include ActsAsMessageable::Model::InstanceMethods
|
16
|
-
end
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
module InstanceMethods
|
21
|
-
def messages(options = {}, &block)
|
22
|
-
result = options.blank? ? (self.received + self.sent) : ActsAsMessageable::Message.scoped
|
23
|
-
filter(result, options, &block)
|
24
|
-
end
|
25
|
-
|
26
|
-
def received(options = {}, &block)
|
27
|
-
if options[:all]
|
28
|
-
result = self.received_messages
|
29
|
-
elsif options[:deleted]
|
30
|
-
result = self.received_messages.where(:recipient_delete => true)
|
31
|
-
else
|
32
|
-
result = self.received_messages.where(:recipient_delete => false)
|
33
|
-
end
|
34
|
-
|
35
|
-
filter(result, options, &block)
|
36
|
-
end
|
37
|
-
|
38
|
-
def sent(options = {}, &block)
|
39
|
-
if options[:all]
|
40
|
-
result = self.sent_messages
|
41
|
-
elsif options[:deleted]
|
42
|
-
result = self.sent_messages.where(:sender_delete => true)
|
43
|
-
else
|
44
|
-
result = self.sent_messages.where(:sender_delete => false)
|
45
|
-
end
|
46
|
-
|
47
|
-
filter(result, options, &block)
|
48
|
-
end
|
49
|
-
|
50
|
-
def send_message(to, topic, body)
|
51
|
-
@message = ActsAsMessageable::Message.create!(:topic => topic, :body => body)
|
52
|
-
|
53
|
-
self.sent_messages << @message
|
54
|
-
to.received_messages << @message
|
55
|
-
end
|
56
|
-
|
57
|
-
def delete_message(message)
|
58
|
-
current_user = self
|
59
|
-
|
60
|
-
if message.received_messageable == current_user
|
61
|
-
message.update_attributes!(:recipient_delete => true)
|
62
|
-
elsif message.sent_messageable == current_user
|
63
|
-
message.update_attributes!(:sender_delete => true)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
private
|
68
|
-
|
69
|
-
def filter(result, options = {}, &block)
|
70
|
-
current_user = self
|
71
|
-
|
72
|
-
options.each do |key, value|
|
73
|
-
case key
|
74
|
-
when :from then
|
75
|
-
result = result.messages_from(value, current_user)
|
76
|
-
when :to then
|
77
|
-
result = result.messages_to(value, current_user)
|
78
|
-
when :id then
|
79
|
-
result = result.message_id(value)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
result.each do |message|
|
84
|
-
block.call(message)
|
85
|
-
delete_message(message) if message.delete_message
|
86
|
-
end if block_given?
|
87
|
-
|
88
|
-
result
|
89
|
-
end
|
90
|
-
|
91
|
-
end
|
92
|
-
|
93
|
-
end
|
94
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
module ActsAsMessageable
|
2
|
-
class Message < ::ActiveRecord::Base
|
3
|
-
belongs_to :received_messageable, :polymorphic => true
|
4
|
-
belongs_to :sent_messageable, :polymorphic => true
|
5
|
-
|
6
|
-
attr_accessible :topic,
|
7
|
-
:body,
|
8
|
-
:received_messageable_type,
|
9
|
-
:received_messageable_id,
|
10
|
-
:sent_messageable_type,
|
11
|
-
:sent_messageable_id,
|
12
|
-
:opened,
|
13
|
-
:recipient_delete,
|
14
|
-
:sender_delete
|
15
|
-
|
16
|
-
attr_accessor :delete_message
|
17
|
-
|
18
|
-
scope :messages_from, lambda { |*args| where("sent_messageable_id = :sender", :sender => args.first).
|
19
|
-
where("received_messageable_id = :receiver", :receiver => args.last) }
|
20
|
-
scope :messages_to, lambda { |*args| where("received_messageable_id = :receiver", :receiver => args.first).
|
21
|
-
where("sent_messageable_id = :sender", :sender => args.last)}
|
22
|
-
scope :message_id, lambda { |*args| where("id = :id", :id => args.first) }
|
23
|
-
|
24
|
-
validates_presence_of :topic ,:body
|
25
|
-
|
26
|
-
def open?
|
27
|
-
self.opened?
|
28
|
-
end
|
29
|
-
|
30
|
-
def open
|
31
|
-
update_attributes!(:opened => true)
|
32
|
-
end
|
33
|
-
|
34
|
-
def mark_as_read
|
35
|
-
open
|
36
|
-
end
|
37
|
-
|
38
|
-
def close
|
39
|
-
update_attributes!(:opened => false)
|
40
|
-
end
|
41
|
-
|
42
|
-
def mark_as_unread
|
43
|
-
close
|
44
|
-
end
|
45
|
-
|
46
|
-
def from
|
47
|
-
"#{self.sent_messageable_type}".constantize.find(self.sent_messageable_id)
|
48
|
-
end
|
49
|
-
|
50
|
-
def to
|
51
|
-
"#{self.received_messageable_type}".constantize.find(self.received_messageable_id)
|
52
|
-
end
|
53
|
-
|
54
|
-
def delete
|
55
|
-
self.delete_message = true
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
59
|
-
end
|
data/test/message_test.rb
DELETED
@@ -1,114 +0,0 @@
|
|
1
|
-
require 'test/unit'
|
2
|
-
require "rubygems"
|
3
|
-
|
4
|
-
require File.expand_path('../../lib/acts-as-messageable.rb', __FILE__)
|
5
|
-
|
6
|
-
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
7
|
-
|
8
|
-
def create_db
|
9
|
-
ActiveRecord::Schema.define(:version => 1) do
|
10
|
-
create_table :messages do |t|
|
11
|
-
t.string :topic
|
12
|
-
t.text :body
|
13
|
-
t.references :received_messageable, :polymorphic => true
|
14
|
-
t.references :sent_messageable, :polymorphic => true
|
15
|
-
t.boolean :opened, :default => false
|
16
|
-
t.boolean :opened, :default => false
|
17
|
-
t.boolean :recipient_delete, :default => false
|
18
|
-
t.boolean :sender_delete, :default => false
|
19
|
-
end
|
20
|
-
|
21
|
-
create_table :users do |t|
|
22
|
-
t.string :email
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
def drop_db
|
30
|
-
ActiveRecord::Base.connection.tables.each do |table|
|
31
|
-
ActiveRecord::Base.connection.drop_table(table)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class User < ActiveRecord::Base
|
36
|
-
acts_as_messageable
|
37
|
-
end
|
38
|
-
|
39
|
-
class MessageTest < Test::Unit::TestCase
|
40
|
-
def setup
|
41
|
-
create_db
|
42
|
-
User.create!(:email => "user1@users.com")
|
43
|
-
User.create!(:email => "user2@users.com")
|
44
|
-
end
|
45
|
-
|
46
|
-
def teardown
|
47
|
-
drop_db
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_send_message
|
51
|
-
u1 = User.first
|
52
|
-
u2 = User.last
|
53
|
-
|
54
|
-
u1.send_message(u2, "Topic", "Body")
|
55
|
-
u2.send_message(u1, "Topic2", "Body2")
|
56
|
-
|
57
|
-
assert_equal ["Topic", "Topic2"], ActsAsMessageable::Message.find(:all).map(&:topic)
|
58
|
-
assert_equal ["Body", "Body2"], ActsAsMessageable::Message.find(:all).map(&:body)
|
59
|
-
assert_equal u1.id, ActsAsMessageable::Message.find(:first, :conditions => { :topic => "Topic" }).sent_messageable_id
|
60
|
-
assert_equal u2.id, ActsAsMessageable::Message.find(:first, :conditions => { :topic => "Topic" }).received_messageable_id
|
61
|
-
|
62
|
-
assert_equal u2.id, ActsAsMessageable::Message.find(:first, :conditions => { :topic => "Topic2" }).sent_messageable_id
|
63
|
-
assert_equal u1.id, ActsAsMessageable::Message.find(:first, :conditions => { :topic => "Topic2" }).received_messageable_id
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_received
|
67
|
-
u1 = User.first
|
68
|
-
u2 = User.last
|
69
|
-
|
70
|
-
u1.send_message(u2, "Topic", "Body")
|
71
|
-
u1.send_message(u2, "Topic2", "Body2")
|
72
|
-
|
73
|
-
assert_equal ["Topic", "Topic2"], u2.received.map(&:topic)
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_sent
|
77
|
-
u1 = User.first
|
78
|
-
u2 = User.last
|
79
|
-
|
80
|
-
u1.send_message(u2, "Topic", "Body")
|
81
|
-
u1.send_message(u2, "Topic2", "Body2")
|
82
|
-
|
83
|
-
assert_equal ["Topic", "Topic2"], u1.sent.map(&:topic)
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_messages
|
87
|
-
u1 = User.first
|
88
|
-
u2 = User.last
|
89
|
-
|
90
|
-
u1.send_message(u2, "Topic", "Body")
|
91
|
-
u1.send_message(u2, "Topic2", "Body2")
|
92
|
-
|
93
|
-
assert_equal ["Topic", "Topic2"], u2.messages(:from => u1).map(&:topic)
|
94
|
-
assert_equal ["Topic", "Topic2"], u1.messages(:to => u2).map(&:topic)
|
95
|
-
assert_equal ["Topic"], u1.messages(:to => u2, :id => 1).map(&:topic)
|
96
|
-
assert_equal ["Topic2"], u1.messages(:id => 2).map(&:topic)
|
97
|
-
end
|
98
|
-
|
99
|
-
def test_delete_message
|
100
|
-
u1 = User.first
|
101
|
-
u2 = User.last
|
102
|
-
|
103
|
-
u1.send_message(u2, "Topic", "Body")
|
104
|
-
u1.send_message(u2, "Topic2", "Body2")
|
105
|
-
|
106
|
-
u1.messages do |m|
|
107
|
-
m.delete
|
108
|
-
end
|
109
|
-
|
110
|
-
assert_equal [], u1.messages
|
111
|
-
assert_equal ["Topic", "Topic2"], u2.messages.map(&:topic)
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|