inkwell 1.2.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
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|