inkwell 1.2.0 → 1.4.1

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.
Files changed (29) hide show
  1. data/app/models/inkwell/community_user.rb +15 -0
  2. data/app/models/inkwell/following.rb +8 -0
  3. data/db/migrate/20130212130888_refactor_followings_relation.rb +27 -0
  4. data/db/migrate/20130212130898_refactor_user_community_relation.rb +72 -0
  5. data/db/migrate/20130212130908_refactor_invites_bans_mutes.rb +48 -0
  6. data/lib/acts_as_inkwell_community/base.rb +185 -180
  7. data/lib/acts_as_inkwell_user/base.rb +72 -30
  8. data/lib/common/base.rb +21 -0
  9. data/lib/inkwell/version.rb +1 -1
  10. data/test/dummy/db/development.sqlite3 +0 -0
  11. data/test/dummy/db/migrate/20130227154519_refactor_followings_relation.inkwell.rb +28 -0
  12. data/test/dummy/db/migrate/20130228115224_refactor_user_community_relation.inkwell.rb +73 -0
  13. data/test/dummy/db/migrate/20130312084529_refactor_invites_bans_mutes.inkwell.rb +49 -0
  14. data/test/dummy/db/schema.rb +33 -12
  15. data/test/dummy/db/test.sqlite3 +0 -0
  16. data/test/dummy/log/development.log +1986 -0
  17. data/test/dummy/log/test.log +0 -0
  18. data/test/dummy/spec/functional/community_spec.rb +513 -196
  19. data/test/dummy/spec/functional/following_spec.rb +55 -7
  20. data/test/dummy_without_community/db/development.sqlite3 +0 -0
  21. data/test/dummy_without_community/db/migrate/20130313083915_refactor_followings_relation.inkwell.rb +28 -0
  22. data/test/dummy_without_community/db/migrate/20130313083916_refactor_user_community_relation.inkwell.rb +73 -0
  23. data/test/dummy_without_community/db/migrate/20130313083917_refactor_invites_bans_mutes.inkwell.rb +49 -0
  24. data/test/dummy_without_community/db/schema.rb +12 -5
  25. data/test/dummy_without_community/db/test.sqlite3 +0 -0
  26. data/test/dummy_without_community/log/development.log +78 -0
  27. data/test/dummy_without_community/log/test.log +12652 -0
  28. data/test/dummy_without_community/spec/functional/following_spec.rb +20 -7
  29. metadata +31 -14
@@ -0,0 +1,15 @@
1
+ module Inkwell
2
+ if ::Inkwell::Engine::config.respond_to?('community_table')
3
+ class CommunityUser < ActiveRecord::Base
4
+ attr_accessible "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id", "#{::Inkwell::Engine::config.community_table.to_s.singularize}_id",
5
+ :is_writer, :is_admin, :admin_level, :muted, :user_access, :active, :banned, :asked_invitation
6
+ belongs_to ::Inkwell::Engine::config.community_table.to_s.singularize.to_sym
7
+ belongs_to ::Inkwell::Engine::config.user_table.to_s.singularize.to_sym
8
+ belongs_to :admins, :foreign_key => "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
9
+ belongs_to :writers, :foreign_key => "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
10
+ belongs_to :muted_users, :foreign_key => "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
11
+ belongs_to :banned_users, :foreign_key => "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
12
+ belongs_to :asked_invitation_users, :foreign_key => "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module Inkwell
2
+ class Following < ActiveRecord::Base
3
+ attr_accessible :followed_id, :follower_id
4
+
5
+ belongs_to :following, :foreign_key => :followed_id
6
+ belongs_to :follower, :foreign_key => :follower_id
7
+ end
8
+ end
@@ -0,0 +1,27 @@
1
+ class RefactorFollowingsRelation < ActiveRecord::Migration
2
+ def change
3
+ create_table :inkwell_followings do |t|
4
+ t.integer :follower_id
5
+ t.integer :followed_id
6
+
7
+ t.timestamps
8
+ end
9
+ add_column ::Inkwell::Engine::config.user_table, :follower_count, :integer, :default => 0
10
+ add_column ::Inkwell::Engine::config.user_table, :following_count, :integer, :default => 0
11
+
12
+ user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
13
+ user_class.all.each do |user|
14
+ followings_ids = ActiveSupport::JSON.decode user.followings_ids
15
+ followers_ids = ActiveSupport::JSON.decode user.followers_ids
16
+ user.following_count = followings_ids.size
17
+ user.follower_count = followers_ids.size
18
+ user.save
19
+ followings_ids.each do |followed_id|
20
+ ::Inkwell::Following.create :follower_id => user.id, :followed_id => followed_id
21
+ end
22
+ end
23
+
24
+ remove_column ::Inkwell::Engine::config.user_table, :followers_ids
25
+ remove_column ::Inkwell::Engine::config.user_table, :followings_ids
26
+ end
27
+ end
@@ -0,0 +1,72 @@
1
+ class RefactorUserCommunityRelation < ActiveRecord::Migration
2
+ def change
3
+ if ::Inkwell::Engine::config.respond_to?('community_table')
4
+ user_id = "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
5
+ community_id = "#{::Inkwell::Engine::config.community_table.to_s.singularize}_id"
6
+
7
+ create_table :inkwell_community_users do |t|
8
+ t.integer user_id
9
+ t.integer community_id
10
+ t.string :user_access, :default => "r"
11
+ t.boolean :is_admin, :default => false
12
+ t.integer :admin_level
13
+ t.boolean :muted, :default => false
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_column ::Inkwell::Engine::config.community_table, :user_count, :integer, :default => 0
19
+ add_column ::Inkwell::Engine::config.community_table, :writer_count, :integer, :default => 0
20
+ add_column ::Inkwell::Engine::config.community_table, :admin_count, :integer, :default => 0
21
+ add_column ::Inkwell::Engine::config.community_table, :muted_count, :integer, :default => 0
22
+ add_column ::Inkwell::Engine::config.user_table, :community_count, :integer, :default => 0
23
+
24
+ community_class = Object.const_get ::Inkwell::Engine::config.community_table.to_s.singularize.capitalize
25
+
26
+ community_class.all.each do |community|
27
+ users_ids = ActiveSupport::JSON.decode community.users_ids
28
+ community.user_count = users_ids.size
29
+
30
+ users_ids.each do |uid|
31
+ ::Inkwell::CommunityUser.create user_id => uid, community_id => community.id
32
+ end
33
+
34
+ writers_ids = ActiveSupport::JSON.decode community.writers_ids
35
+ community.writer_count = writers_ids.size
36
+
37
+ writers_ids.each do |uid|
38
+ ::Inkwell::CommunityUser.where(user_id => uid, community_id => community.id).update_all(:user_access => "w")
39
+ end
40
+
41
+ admins_info = ActiveSupport::JSON.decode community.admins_info
42
+ community.admin_count = admins_info.size
43
+
44
+ admins_info.each do |rec|
45
+ ::Inkwell::CommunityUser.where(user_id => rec['admin_id'], community_id => community.id).update_all(:is_admin => true, :admin_level => rec['admin_level'])
46
+ end
47
+
48
+ muted_ids = ActiveSupport::JSON.decode community.muted_ids
49
+ community.muted_count = muted_ids.size
50
+
51
+ muted_ids.each do |uid|
52
+ ::Inkwell::CommunityUser.where(user_id => uid, community_id => community.id).update_all(:muted => true)
53
+ end
54
+
55
+ community.save
56
+ end
57
+
58
+ user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
59
+ user_class.all.each do |user|
60
+ communities_info = ActiveSupport::JSON.decode user.communities_info
61
+ user.community_count = communities_info.size
62
+ user.save
63
+ end
64
+
65
+ remove_column ::Inkwell::Engine::config.community_table, :users_ids
66
+ remove_column ::Inkwell::Engine::config.community_table, :writers_ids
67
+ remove_column ::Inkwell::Engine::config.community_table, :admins_info
68
+ remove_column ::Inkwell::Engine::config.community_table, :muted_ids
69
+ remove_column ::Inkwell::Engine::config.user_table, :communities_info
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,48 @@
1
+ class RefactorInvitesBansMutes < ActiveRecord::Migration
2
+ def change
3
+ if ::Inkwell::Engine::config.respond_to?('community_table')
4
+ user_id = "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
5
+ community_id = "#{::Inkwell::Engine::config.community_table.to_s.singularize}_id"
6
+
7
+ add_column ::Inkwell::Engine::config.community_table, :banned_count, :integer, :default => 0
8
+ add_column ::Inkwell::Engine::config.community_table, :invitation_count, :integer, :default => 0
9
+
10
+ change_column ::Inkwell::Engine::config.community_table, :user_count, :integer, :default => 1
11
+ change_column ::Inkwell::Engine::config.community_table, :admin_count, :integer, :default => 1
12
+ change_column ::Inkwell::Engine::config.community_table, :writer_count, :integer, :default => 1
13
+
14
+ add_column :inkwell_community_users, :active, :boolean, :default => false
15
+ add_column :inkwell_community_users, :banned, :boolean, :default => false
16
+ add_column :inkwell_community_users, :asked_invitation, :boolean, :default => false
17
+
18
+ community_class = Object.const_get ::Inkwell::Engine::config.community_table.to_s.singularize.capitalize
19
+
20
+ community_class.all.each do |community|
21
+ banned_ids = ActiveSupport::JSON.decode community.banned_ids
22
+ community.banned_count = banned_ids.size
23
+ banned_ids.each do |uid|
24
+ relations = ::Inkwell::CommunityUser.where community_id => community.id, user_id => uid
25
+ if relations.empty?
26
+ ::Inkwell::CommunityUser.create community_id => community.id, user_id => uid, :active => false, :banned => true
27
+ else
28
+ relation = relations.first
29
+ relation.active = false
30
+ relation.banned = true
31
+ relation.save
32
+ end
33
+ end
34
+
35
+ invitations_uids = ActiveSupport::JSON.decode community.invitations_uids
36
+ community.invitation_count = invitations_uids.size
37
+ invitations_uids.each do |uid|
38
+ ::Inkwell::CommunityUser.create community_id => community.id, user_id => uid, :active => false, :asked_invitation => true
39
+ end
40
+
41
+ community.save
42
+ end
43
+
44
+ remove_column ::Inkwell::Engine::config.community_table, :banned_ids
45
+ remove_column ::Inkwell::Engine::config.community_table, :invitations_uids
46
+ end
47
+ end
48
+ end
@@ -12,9 +12,18 @@ module Inkwell
12
12
  def acts_as_inkwell_community
13
13
  validates :owner_id, :presence => true
14
14
 
15
+ if ::Inkwell::Engine::config.respond_to?('community_table')
16
+ has_many :communities_users, :class_name => 'Inkwell::CommunityUser'
17
+ has_many :users, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.active" => true}
18
+ has_many :admins, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.is_admin" => true, "inkwell_community_users.active" => true}
19
+ has_many :writers, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.user_access" => ::Inkwell::Constants::CommunityAccessLevels::WRITE, "inkwell_community_users.active" => true}
20
+ has_many :muted_users, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.muted" => true, "inkwell_community_users.active" => true}
21
+ has_many :banned_users, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.banned" => true}
22
+ has_many :asked_invitation_users, :through => :communities_users, :class_name => ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize, :conditions => {"inkwell_community_users.asked_invitation" => true}
23
+ end
24
+
15
25
  after_create :processing_a_community
16
26
  before_destroy :destroy_community_processing
17
-
18
27
  include ::Inkwell::ActsAsInkwellCommunity::InstanceMethods
19
28
  end
20
29
  end
@@ -27,26 +36,29 @@ module Inkwell
27
36
  def add_user(options = {})
28
37
  options.symbolize_keys!
29
38
  user = options[:user]
30
- raise "this user is already in this community" if self.include_user? user
31
- raise "this user is banned" if self.include_banned_user? user
32
-
33
- users_ids = ActiveSupport::JSON.decode self.users_ids
34
- users_ids << user.id
35
- self.users_ids = ActiveSupport::JSON.encode users_ids
36
- if (self.default_user_access == CommunityAccessLevels::WRITE) && !(self.include_muted_user? user)
37
- writers_ids = ActiveSupport::JSON.decode self.writers_ids
38
- writers_ids << user.id
39
- self.writers_ids = ActiveSupport::JSON.encode writers_ids
39
+ check_user user
40
+
41
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
42
+
43
+ if relation
44
+ raise "this user is already in this community" if relation.active
45
+ raise "this user is banned" if relation.banned
46
+
47
+ relation.asked_invitation = false if relation.asked_invitation
48
+ relation.user_access = self.default_user_access
49
+ relation.active = true
50
+ relation.save
51
+ else
52
+ relation = ::Inkwell::CommunityUser.create user_id_attr => user.id, community_id_attr => self.id, :user_access => self.default_user_access, :active => true
40
53
  end
41
- self.save
42
54
 
43
- communities_info = ActiveSupport::JSON.decode user.communities_info
44
- communities_info << Hash[HashParams::COMMUNITY_ID => self.id, HashParams::ACCESS_LEVEL => self.default_user_access]
45
- user.communities_info = ActiveSupport::JSON.encode communities_info
55
+
56
+ self.user_count += 1
57
+ self.writer_count += 1 if relation.user_access == CommunityAccessLevels::WRITE
58
+ self.save
59
+ user.community_count += 1
46
60
  user.save
47
61
 
48
- post_class = Object.const_get ::Inkwell::Engine::config.post_table.to_s.singularize.capitalize
49
- user_id_attr = "#{::Inkwell::Engine::config.user_table.to_s.singularize}_id"
50
62
  ::Inkwell::BlogItem.where(:owner_id => self.id, :owner_type => OwnerTypes::COMMUNITY).order("created_at DESC").limit(10).each do |blog_item|
51
63
  next if post_class.find(blog_item.item_id).send(user_id_attr) == user.id
52
64
 
@@ -76,25 +88,23 @@ module Inkwell
76
88
  raise "admin has no permissions to delete this user from community" if (self.admin_level_of(user) <= self.admin_level_of(admin)) && (user != admin)
77
89
  end
78
90
 
79
- users_ids = ActiveSupport::JSON.decode self.users_ids
80
- users_ids.delete user.id
81
- self.users_ids = ActiveSupport::JSON.encode users_ids
82
-
83
- writers_ids = ActiveSupport::JSON.decode self.writers_ids
84
- writers_ids.delete user.id
85
- self.writers_ids = ActiveSupport::JSON.encode writers_ids
86
-
87
- admins_info = ActiveSupport::JSON.decode self.admins_info
88
- admins_info.delete_if{|item| item['admin_id'] == user.id}
89
- self.admins_info = ActiveSupport::JSON.encode admins_info
91
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
90
92
 
93
+ self.user_count -= 1
94
+ self.writer_count -= 1 if relation.user_access == CommunityAccessLevels::WRITE
95
+ self.admin_count -= 1 if relation.is_admin
96
+ self.muted_count -= 1 if relation.muted
91
97
  self.save
92
-
93
- communities_info = ActiveSupport::JSON.decode user.communities_info
94
- communities_info.delete_if {|item| item[HashParams::COMMUNITY_ID] == self.id}
95
- user.communities_info = ActiveSupport::JSON.encode communities_info
98
+ user.community_count -= 1
96
99
  user.save
97
100
 
101
+ if relation.muted
102
+ relation.active = false
103
+ relation.save
104
+ else
105
+ relation.destroy
106
+ end
107
+
98
108
  timeline_items = ::Inkwell::TimelineItem.where(:owner_id => user.id, :owner_type => OwnerTypes::USER).where "from_source like '%{\"community_id\":#{self.id}%'"
99
109
  timeline_items.delete_all :has_many_sources => false
100
110
  timeline_items.each do |item|
@@ -108,14 +118,12 @@ module Inkwell
108
118
 
109
119
  def include_writer?(user)
110
120
  check_user user
111
- writers_ids = ActiveSupport::JSON.decode self.writers_ids
112
- writers_ids.include? user.id
121
+ ::Inkwell::CommunityUser.exists? user_id_attr => user.id, community_id_attr => self.id, :user_access => CommunityAccessLevels::WRITE, :active => true
113
122
  end
114
123
 
115
124
  def include_user?(user)
116
125
  check_user user
117
- communities_info = ActiveSupport::JSON.decode user.communities_info
118
- (communities_info.index{|item| item[HashParams::COMMUNITY_ID] == self.id}) ? true : false
126
+ ::Inkwell::CommunityUser.exists? user_id_attr => user.id, community_id_attr => self.id, :active => true
119
127
  end
120
128
 
121
129
  def mute_user(options = {})
@@ -126,16 +134,19 @@ module Inkwell
126
134
  raise "admin should be passed in params" unless admin
127
135
  check_user user
128
136
  check_user admin
137
+
138
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
139
+
129
140
  raise "admin is not admin" unless self.include_admin? admin
130
- raise "user should be a member of this community" unless self.include_user? user
131
- raise "this user is already muted" if self.include_muted_user? user
141
+ raise "user should be a member of this community" unless relation
142
+ raise "this user is already muted" if relation.muted
132
143
  raise "it is impossible to mute yourself" if user == admin
133
- raise "admin has no permissions to mute this user" if (self.include_admin? user) && (admin_level_of(admin) >= admin_level_of(user))
144
+ raise "admin has no permissions to mute this user" if (relation.is_admin) && (admin_level_of(admin) >= relation.admin_level)
134
145
 
146
+ relation.muted = true
147
+ relation.save
135
148
 
136
- muted_ids = ActiveSupport::JSON.decode self.muted_ids
137
- muted_ids << user.id
138
- self.muted_ids = ActiveSupport::JSON.encode muted_ids
149
+ self.muted_count += 1
139
150
  self.save
140
151
  end
141
152
 
@@ -147,21 +158,24 @@ module Inkwell
147
158
  raise "admin should be passed in params" unless admin
148
159
  check_user user
149
160
  check_user admin
161
+
162
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
163
+
150
164
  raise "admin is not admin" unless self.include_admin? admin
151
- raise "user should be a member of this community" unless self.include_user? user
152
- raise "this user is not muted" unless self.include_muted_user? user
153
- raise "admin has no permissions to unmute this user" if (self.include_admin? user) && (admin_level_of(admin) >= admin_level_of(user))
165
+ raise "user should be a member of this community" unless relation
166
+ raise "this user is not muted" unless relation.muted
167
+ raise "admin has no permissions to unmute this user" if (relation.is_admin) && (admin_level_of(admin) >= relation.admin_level)
168
+
169
+ relation.muted = false
170
+ relation.save
154
171
 
155
- muted_ids = ActiveSupport::JSON.decode self.muted_ids
156
- muted_ids.delete user.id
157
- self.muted_ids = ActiveSupport::JSON.encode muted_ids
172
+ self.muted_count -= 1
158
173
  self.save
159
174
  end
160
175
 
161
176
  def include_muted_user?(user)
162
177
  check_user user
163
- muted_ids = ActiveSupport::JSON.decode self.muted_ids
164
- muted_ids.include? user.id
178
+ ::Inkwell::CommunityUser.exists? user_id_attr => user.id, community_id_attr => self.id, :muted => true, :active => true
165
179
  end
166
180
 
167
181
  def ban_user(options = {})
@@ -173,22 +187,23 @@ module Inkwell
173
187
  check_user user
174
188
  check_user admin
175
189
  raise "admin is not admin" unless self.include_admin? admin
176
- if self.public
177
- raise "user should be a member of public community" unless self.include_user?(user)
190
+ raise "admin has no permissions to ban this user" if (self.include_admin? user) && (admin_level_of(admin) >= admin_level_of(user))
191
+
192
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
193
+ raise "user should be a member of community or send invitation request to it" unless relation
194
+ raise "this user is already banned" if relation.banned
195
+ relation.banned = true
196
+ relation.active = false
197
+ if relation.asked_invitation
198
+ relation.asked_invitation = false
199
+ self.invitation_count -= 1
178
200
  else
179
- raise "user should be a member of private community or send invitation request to it" unless self.include_user?(user) || self.include_invitation_request?(user)
201
+ self.user_count -= 1
180
202
  end
181
- raise "this user is already banned" if self.include_banned_user? user
182
- raise "admin has no permissions to ban this user" if (self.include_admin? user) && (admin_level_of(admin) >= admin_level_of(user))
203
+ relation.save
183
204
 
184
- banned_ids = ActiveSupport::JSON.decode self.banned_ids
185
- banned_ids << user.id
186
- self.banned_ids = ActiveSupport::JSON.encode banned_ids
205
+ self.banned_count += 1
187
206
  self.save
188
- unless self.public
189
- self.reject_invitation_request :admin => admin, :user => user if self.include_invitation_request? user
190
- end
191
- self.remove_user :admin => admin, :user => user
192
207
  end
193
208
 
194
209
  def unban_user(options = {})
@@ -200,18 +215,20 @@ module Inkwell
200
215
  check_user user
201
216
  check_user admin
202
217
  raise "admin is not admin" unless self.include_admin? admin
203
- raise "this user is not banned" unless self.include_banned_user? user
204
218
 
205
- banned_ids = ActiveSupport::JSON.decode self.banned_ids
206
- banned_ids.delete user.id
207
- self.banned_ids = ActiveSupport::JSON.encode banned_ids
219
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
220
+ raise "this user is not banned" unless relation || relation.banned
221
+
222
+ relation.banned = false
223
+ relation.active = true unless relation.asked_invitation
224
+ relation.save
225
+
226
+ self.banned_count -= 1
208
227
  self.save
209
228
  end
210
229
 
211
230
  def include_banned_user?(user)
212
- check_user user
213
- banned_ids = ActiveSupport::JSON.decode self.banned_ids
214
- banned_ids.include? user.id
231
+ ::Inkwell::CommunityUser.exists? :community_id => self.id, :user_id => user.id, :banned => true
215
232
  end
216
233
 
217
234
  def add_admin(options = {})
@@ -222,23 +239,27 @@ module Inkwell
222
239
  raise "admin should be passed in params" unless admin
223
240
  check_user user
224
241
  check_user admin
225
- raise "user is already admin" if self.include_admin? user
226
- raise "admin is not admin" unless self.include_admin? admin
227
- raise "user should be a member of this community" unless self.include_user? user
228
242
 
229
- self.unmute_user :user => user, :admin => admin if self.include_muted_user? user
243
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).first
230
244
 
231
- unless self.include_writer? user
232
- writers_ids = ActiveSupport::JSON.decode self.writers_ids
233
- writers_ids << user.id
234
- self.writers_ids = ActiveSupport::JSON.encode writers_ids
235
- end
245
+ raise "user should be in the community" unless relation
246
+ raise "user is already admin" if relation.is_admin
247
+ raise "admin is not admin" unless self.include_admin? admin
248
+ raise "user should be a member of this community" unless relation
236
249
 
237
- admin_level_granted_for_user = admin_level_of(admin) + 1
250
+ if relation.muted
251
+ relation.muted = false
252
+ self.muted_count -= 1
253
+ end
254
+ unless relation.user_access == CommunityAccessLevels::WRITE
255
+ relation.user_access = CommunityAccessLevels::WRITE
256
+ self.writer_count += 1
257
+ end
258
+ relation.admin_level = admin_level_of(admin) + 1
259
+ relation.is_admin = true
260
+ relation.save
238
261
 
239
- admins_info = ActiveSupport::JSON.decode self.admins_info
240
- admins_info << Hash['admin_id' => user.id, 'admin_level' => admin_level_granted_for_user]
241
- self.admins_info = ActiveSupport::JSON.encode admins_info
262
+ self.admin_count += 1
242
263
  self.save
243
264
  end
244
265
 
@@ -253,24 +274,22 @@ module Inkwell
253
274
  raise "admin has no permissions to delete this user from admins" if (admin_level_of(admin) >= admin_level_of(user)) && (user != admin)
254
275
  raise "community owner can not be removed from admins" if admin_level_of(user) == 0
255
276
 
256
- admins_info = ActiveSupport::JSON.decode self.admins_info
257
- admins_info.delete_if{|rec| rec['admin_id'] == user.id}
258
- self.admins_info = ActiveSupport::JSON.encode admins_info
277
+ ::Inkwell::CommunityUser.where(user_id_attr => user.id, community_id_attr => self.id).update_all :is_admin => false, :admin_level => nil
278
+
279
+ self.admin_count -= 1
259
280
  self.save
260
281
  end
261
282
 
262
283
  def admin_level_of(admin)
263
- admin_positions = ActiveSupport::JSON.decode self.admins_info
264
- index = admin_positions.index{|item| item['admin_id'] == admin.id}
265
- raise "admin is not admin" unless index
266
- admin_positions[index]['admin_level']
284
+ relation = ::Inkwell::CommunityUser.where(user_id_attr => admin.id, community_id_attr => self.id).first
285
+ raise "this user is not community member" unless relation
286
+ raise "admin is not admin" unless relation.is_admin
287
+ relation.admin_level
267
288
  end
268
289
 
269
290
  def include_admin?(user)
270
291
  check_user user
271
-
272
- admin_positions = ActiveSupport::JSON.decode self.admins_info
273
- (admin_positions.index{|item| item['admin_id'] == user.id}) ? true : false
292
+ ::Inkwell::CommunityUser.exists? user_id_attr => user.id, community_id_attr => self.id, :is_admin => true, :active => true
274
293
  end
275
294
 
276
295
  def add_post(options = {})
@@ -302,9 +321,9 @@ module Inkwell
302
321
  item.save
303
322
  end
304
323
 
305
- self.users_row.each do |user_id|
306
- next if users_with_existing_items.include? user_id
307
- ::Inkwell::TimelineItem.create :item_id => post.id, :owner_id => user_id, :owner_type => OwnerTypes::USER, :item_type => ItemTypes::POST,
324
+ self.users_row.each do |uid|
325
+ next if users_with_existing_items.include? uid
326
+ ::Inkwell::TimelineItem.create :item_id => post.id, :owner_id => uid, :owner_type => OwnerTypes::USER, :item_type => ItemTypes::POST,
308
327
  :from_source => ActiveSupport::JSON.encode([Hash['community_id' => self.id]])
309
328
  end
310
329
  end
@@ -380,30 +399,47 @@ module Inkwell
380
399
  end
381
400
 
382
401
  def users_row
383
- ActiveSupport::JSON.decode self.users_ids
402
+ relations = ::Inkwell::CommunityUser.where community_id_attr => self.id
403
+ result = []
404
+ relations.each do |rel|
405
+ result << rel.send(user_id_attr)
406
+ end
407
+ result
384
408
  end
385
409
 
386
410
  def writers_row
387
- ActiveSupport::JSON.decode self.writers_ids
411
+ relations = ::Inkwell::CommunityUser.where community_id_attr => self.id, :user_access => CommunityAccessLevels::WRITE
412
+ result = []
413
+ relations.each do |rel|
414
+ result << rel.send(user_id_attr)
415
+ end
416
+ result
388
417
  end
389
418
 
390
419
  def admins_row
391
- admins_info = ActiveSupport::JSON.decode self.admins_info
420
+ relations = ::Inkwell::CommunityUser.where community_id_attr => self.id, :is_admin => true
392
421
  result = []
393
- admins_info.each do |rec|
394
- result << rec['admin_id']
422
+ relations.each do |rel|
423
+ result << rel.send(user_id_attr)
395
424
  end
396
425
  result
397
426
  end
398
427
 
399
428
  def create_invitation_request(user)
400
- raise "invitation request was already created" if self.include_invitation_request? user
401
- raise "it is impossible to create request. user is banned in this community" if self.include_banned_user? user
429
+ check_user user
430
+
431
+ relation = ::Inkwell::CommunityUser.where(community_id_attr => self.id, user_id_attr => user.id).first
432
+ if relation
433
+ raise "invitation request was already created" if relation.asked_invitation
434
+ raise "it is impossible to create request. user is banned in this community" if relation.banned
435
+ raise "user is already community member" if relation.active
436
+ raise "there is relation for user who is not member of community and he is not banned and not asked invitation to it"
437
+ end
402
438
  raise "it is impossible to create request for public community" if self.public
403
439
 
404
- invitations_uids = ActiveSupport::JSON.decode self.invitations_uids
405
- invitations_uids << user.id
406
- self.invitations_uids = ActiveSupport::JSON.encode invitations_uids
440
+ ::Inkwell::CommunityUser.create community_id_attr => self.id, user_id_attr => user.id, :asked_invitation => true, :active => false
441
+
442
+ self.invitation_count += 1
407
443
  self.save
408
444
  end
409
445
 
@@ -414,12 +450,15 @@ module Inkwell
414
450
  check_user user
415
451
  check_user admin
416
452
  raise "admin is not admin in this community" unless self.include_admin? admin
417
- raise "this user is already in this community" if self.include_user? user
418
- raise "there is no invitation request for this user" unless self.include_invitation_request? user
453
+
454
+ relation = ::Inkwell::CommunityUser.where(community_id_attr => self.id, user_id_attr => user.id).first
455
+ raise "this user is already in this community" if relation.active
456
+ raise "there is no invitation request for this user" unless relation.asked_invitation
419
457
 
420
458
  self.add_user :user => user
421
459
 
422
- remove_invitation_request user
460
+ self.invitation_count -= 1
461
+ self.save
423
462
  end
424
463
 
425
464
  def reject_invitation_request(options = {})
@@ -428,16 +467,29 @@ module Inkwell
428
467
  admin = options[:admin]
429
468
  check_user user
430
469
  check_user admin
431
- raise "there is no invitation request for this user" unless self.include_invitation_request? user
470
+
471
+ relation = ::Inkwell::CommunityUser.where(community_id_attr => self.id, user_id_attr => user.id).first
472
+ raise "there is no invitation request for this user" unless relation || relation.asked_invitation
432
473
  raise "admin is not admin in this community" unless self.include_admin? admin
433
474
 
434
- remove_invitation_request user
475
+ relation.destroy
476
+
477
+ self.invitation_count -= 1
478
+ self.save
435
479
  end
436
480
 
437
481
  def include_invitation_request?(user)
438
482
  raise "invitations work only for private community. this community is public." if self.public
439
- invitations_uids = ActiveSupport::JSON.decode self.invitations_uids
440
- (invitations_uids.index{|uid| uid == user.id}) ? true : false
483
+ ::Inkwell::CommunityUser.exists? community_id_attr => self.id, user_id_attr => user.id, :asked_invitation => true
484
+ end
485
+
486
+ def invitations_row
487
+ relations = ::Inkwell::CommunityUser.where community_id_attr => self.id, :asked_invitation => true
488
+ result = []
489
+ relations.each do |relation|
490
+ result << relation.send(user_id_attr)
491
+ end
492
+ result
441
493
  end
442
494
 
443
495
  def change_default_access_to_write
@@ -456,98 +508,51 @@ module Inkwell
456
508
 
457
509
  def set_write_access(uids)
458
510
  raise "array with users ids should be passed" unless uids.class == Array
459
- users_ids = self.users_row
460
- matching_ids = users_ids & uids
461
- unless matching_ids.size == uids.size
462
- mismatched_ids = uids - matching_ids
463
- raise "there is no users with ids #{mismatched_ids} in the community"
464
- end
465
-
466
- current_writers_ids = ActiveSupport::JSON.decode self.writers_ids
467
- already_added_ids = current_writers_ids & uids
468
- uids -= already_added_ids
511
+ relations = ::Inkwell::CommunityUser.where user_id_attr => uids, community_id_attr => self.id, :user_access => CommunityAccessLevels::READ, :is_admin => false
512
+ raise "there is different count of passed uids (#{uids.size}) and found users (#{relations.size}) in this community" unless relations.size == uids.size
469
513
 
470
- current_writers_ids += uids
471
- self.writers_ids = ActiveSupport::JSON.encode current_writers_ids
514
+ self.writer_count += relations.size
472
515
  self.save
473
516
 
474
- user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
475
- users = user_class.find uids
476
- users.each do |user|
477
- raise "user with id #{uid} does not exist" unless user
478
- communities_info = ActiveSupport::JSON.decode user.communities_info
479
- index = communities_info.index { |rec| rec[HashParams::COMMUNITY_ID] == self.id }
480
- communities_info[index][HashParams::ACCESS_LEVEL] = CommunityAccessLevels::WRITE
481
- user.communities_info = ActiveSupport::JSON.encode communities_info
482
- user.save
483
- end
517
+ relations.update_all :user_access => CommunityAccessLevels::WRITE
484
518
  end
485
519
 
486
520
  def set_read_access(uids)
487
521
  raise "array with users ids should be passed" unless uids.class == Array
488
- users_ids = self.users_row
489
- matching_ids = users_ids & uids
490
- unless matching_ids.size == uids.size
491
- mismatched_ids = uids - matching_ids
492
- raise "there is no users with ids #{mismatched_ids} in the community"
493
- end
522
+ relations = ::Inkwell::CommunityUser.where user_id_attr => uids, community_id_attr => self.id, :user_access => CommunityAccessLevels::WRITE, :is_admin => false
523
+ raise "there is different count of passed uids (#{uids.size}) and found users (#{relations.size}) in this community" unless relations.size == uids.size
494
524
 
495
- matching_ids = self.admins_row & uids
496
- raise "there is impossible to change access level to read for admins with ids #{matching_ids} in the community" unless matching_ids.empty?
497
-
498
- current_writers_ids = ActiveSupport::JSON.decode self.writers_ids
499
- current_writers_ids -= uids
500
- self.writers_ids = ActiveSupport::JSON.encode current_writers_ids
525
+ self.writer_count -= relations.size
501
526
  self.save
502
527
 
503
- user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
504
- users = user_class.find uids
505
- users.each do |user|
506
- raise "user with id #{uid} does not exist" unless user
507
- communities_info = ActiveSupport::JSON.decode user.communities_info
508
- index = communities_info.index { |rec| rec[HashParams::COMMUNITY_ID] == self.id }
509
- communities_info[index][HashParams::ACCESS_LEVEL] = CommunityAccessLevels::READ
510
- user.communities_info = ActiveSupport::JSON.encode communities_info
511
- user.save
512
- end
528
+ relations.update_all :user_access => CommunityAccessLevels::READ
513
529
  end
514
530
 
515
- private
516
-
517
- def remove_invitation_request(user)
518
- invitations_uids = ActiveSupport::JSON.decode self.invitations_uids
519
- invitations_uids.delete user.id
520
- self.invitations_uids = ActiveSupport::JSON.encode invitations_uids
521
- self.save
531
+ def reader_count
532
+ self.user_count - self.writer_count
522
533
  end
523
534
 
535
+ private
536
+
524
537
  def processing_a_community
525
- user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
526
538
  owner = user_class.find self.owner_id
527
-
528
- communities_info = ActiveSupport::JSON.decode owner.communities_info
529
- communities_info << Hash[HashParams::COMMUNITY_ID => self.id, HashParams::ACCESS_LEVEL => self.default_user_access]
530
- owner.communities_info = ActiveSupport::JSON.encode communities_info
539
+ owner.community_count += 1
531
540
  owner.save
532
541
 
533
- admins_info = [Hash['admin_id' => owner.id, 'admin_level' => 0]]
534
- self.admins_info = ActiveSupport::JSON.encode admins_info
535
- self.users_ids = ActiveSupport::JSON.encode [owner.id]
536
- self.writers_ids = ActiveSupport::JSON.encode [owner.id]
537
- self.save
542
+ ::Inkwell::CommunityUser.create user_id_attr => self.owner_id, community_id_attr => self.id, :is_admin => true, :admin_level => 0,
543
+ :user_access => CommunityAccessLevels::WRITE, :active => true
538
544
  end
539
545
 
540
546
  def destroy_community_processing
541
- user_class = Object.const_get ::Inkwell::Engine::config.user_table.to_s.singularize.capitalize
542
- users_ids = ActiveSupport::JSON.decode self.users_ids
543
- users_ids.each do |user_id|
544
- user = user_class.find user_id
545
- communities_info = ActiveSupport::JSON.decode user.communities_info
546
- communities_info.delete_if {|item| item[HashParams::COMMUNITY_ID] == self.id}
547
- user.communities_info = ActiveSupport::JSON.encode communities_info
547
+ users_ids = self.users_row
548
+ users_ids.each do |uid|
549
+ user = user_class.find uid
550
+ user.community_count -= 1
548
551
  user.save
549
552
  end
550
553
 
554
+ ::Inkwell::CommunityUser.delete_all community_id_attr => self.id
555
+
551
556
  timeline_items = ::Inkwell::TimelineItem.where "from_source like '%{\"community_id\":#{self.id}%'"
552
557
  timeline_items.delete_all :has_many_sources => false
553
558
  timeline_items.each do |item|