social_stream-base 0.20.2 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/btn/public.png +0 -0
- data/app/assets/images/btn/restricted.png +0 -0
- data/app/assets/javascripts/social_stream.timeline.js +2 -0
- data/app/assets/javascripts/social_stream.wall.js.erb +10 -1
- data/app/assets/stylesheets/activities.css.scss.erb +13 -2
- data/app/assets/stylesheets/base.css.scss +1 -1
- data/app/controllers/audience_controller.rb +16 -0
- data/app/models/activity.rb +111 -39
- data/app/models/activity_object.rb +1 -9
- data/app/models/actor.rb +42 -53
- data/app/models/contact.rb +0 -21
- data/app/models/tie.rb +1 -1
- data/app/views/activities/_new.html.erb +2 -2
- data/app/views/activities/_options.html.erb +7 -1
- data/app/views/audience/_list.html.erb +8 -0
- data/app/views/audience/index.js.erb +1 -0
- data/config/locales/en.yml +1 -0
- data/config/locales/es.yml +1 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20120526171311_remove_activity_channels.rb +35 -0
- data/lib/social_stream/ability/base.rb +3 -1
- data/lib/social_stream/base/engine.rb +0 -1
- data/lib/social_stream/base/version.rb +1 -1
- data/lib/social_stream-base.rb +0 -1
- data/lib/tasks/db/populate.rake +6 -4
- data/spec/controllers/audience_controller_spec.rb +40 -0
- data/spec/controllers/comments_controller_spec.rb +3 -3
- data/spec/factories/activity.rb +12 -6
- data/spec/models/tie_spec.rb +7 -4
- metadata +9 -5
- data/app/assets/images/btn/btn_security.png +0 -0
- data/app/models/channel.rb +0 -64
- data/lib/social_stream/models/channeled.rb +0 -56
Binary file
|
Binary file
|
@@ -38,6 +38,12 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
38
38
|
});
|
39
39
|
}
|
40
40
|
|
41
|
+
var changeSecurityImage = function(type) {
|
42
|
+
$('#security_chzn .chzn-choices').
|
43
|
+
css('background-image', 'url(<%= asset_path('btn/') %>' + type + '.png)');
|
44
|
+
}
|
45
|
+
|
46
|
+
|
41
47
|
var initSecuritySelect = function(){
|
42
48
|
var default_security_width = '100px';
|
43
49
|
|
@@ -63,6 +69,9 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
63
69
|
chosen.results_update_field();
|
64
70
|
}
|
65
71
|
}
|
72
|
+
changeSecurityImage('public');
|
73
|
+
} else {
|
74
|
+
changeSecurityImage('restricted');
|
66
75
|
}
|
67
76
|
});
|
68
77
|
|
@@ -145,6 +154,6 @@ SocialStream.Wall = (function(SS, $, undefined){
|
|
145
154
|
addInitCallback: addInitCallback,
|
146
155
|
init: init,
|
147
156
|
activateAntiRebounds: activateAntiRebounds,
|
148
|
-
unblockForms: unblockForms
|
157
|
+
unblockForms: unblockForms
|
149
158
|
};
|
150
159
|
}) (SocialStream, jQuery)
|
@@ -27,7 +27,7 @@
|
|
27
27
|
|
28
28
|
#security_chzn .chzn-choices {
|
29
29
|
padding-left: 20px;
|
30
|
-
background: url('btn/
|
30
|
+
background: url('btn/restricted.png') no-repeat 10px center;
|
31
31
|
}
|
32
32
|
/******************* WALL - ACTIVITY ***************/
|
33
33
|
.super_activity{width: 95%;}
|
@@ -55,7 +55,6 @@
|
|
55
55
|
|
56
56
|
.security, .post_time_ago, .verb_comment, .verb_like, .verb_comment, .verb_delete{ display: inline-block;}
|
57
57
|
|
58
|
-
|
59
58
|
/************* ACTIVITY - FOOTER *********/
|
60
59
|
.space_comments { padding-top: 1px; padding-bottom: 1px;}
|
61
60
|
.space_activities { text-align:center; padding: 0px 0px 0px 1px; width:100%;}
|
@@ -88,3 +87,15 @@
|
|
88
87
|
.input_new_comments_container{min-height: 30px; position: relative; }
|
89
88
|
|
90
89
|
.activity_likes{ margin-bottom: 2px; }
|
90
|
+
|
91
|
+
.timeline-130 {
|
92
|
+
width: 130px;
|
93
|
+
margin: 10px;
|
94
|
+
float: left;
|
95
|
+
}
|
96
|
+
|
97
|
+
.audience_logo {
|
98
|
+
padding: 2px;
|
99
|
+
display: inline-block;
|
100
|
+
}
|
101
|
+
|
@@ -137,7 +137,7 @@ div.chzn-container ul.chzn-choices li.search-field input{ cursor:pointer;}
|
|
137
137
|
|
138
138
|
/*************MENU ICON SECTION**********/
|
139
139
|
.menu_header{ border-bottom: thin solid $separation-color; width:14.5em; padding-left:3px; padding-right:3px;}
|
140
|
-
.menu_icon{ vertical-align: middle; padding-bottom: 3px; padding-right:
|
140
|
+
.menu_icon{ vertical-align: middle; padding-bottom: 3px; padding-right: 2px; padding-left: 2px;
|
141
141
|
display: inline-block;}
|
142
142
|
|
143
143
|
/*************SPACES SECTION *************/
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class AudienceController < ApplicationController
|
2
|
+
before_filter :read_activity
|
3
|
+
|
4
|
+
respond_to :js
|
5
|
+
|
6
|
+
def index
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def read_activity
|
12
|
+
@activity = Activity.find params[:activity_id]
|
13
|
+
|
14
|
+
authorize! :read, @activity
|
15
|
+
end
|
16
|
+
end
|
data/app/models/activity.rb
CHANGED
@@ -1,21 +1,32 @@
|
|
1
1
|
# Activities follow the {Activity Streams}[http://activitystrea.ms/] standard.
|
2
2
|
#
|
3
|
-
#
|
4
|
-
# Every activity is attached to a {Channel}, which defines the sender and the receiver of the {Activity}
|
3
|
+
# Every {Activity} has an {#author}, {#user_author} and {#owner}
|
5
4
|
#
|
6
|
-
#
|
7
|
-
#
|
5
|
+
# author:: Is the {SocialStream::Models::Subject subject} that originated
|
6
|
+
# the activity. The entity that posted something, liked, etc..
|
8
7
|
#
|
9
|
-
#
|
10
|
-
#
|
8
|
+
# user_author:: The {User} logged in when the {Activity} was created.
|
9
|
+
# If the {User} has not changed the session to represent
|
10
|
+
# other entity (a {Group} for example), the user_author
|
11
|
+
# will be the same as the author.
|
11
12
|
#
|
12
|
-
#
|
13
|
+
# owner:: The {SocialStream::Models::Subject subject} whose wall was posted
|
14
|
+
# or comment was liked, etc..
|
15
|
+
#
|
16
|
+
# == {Audience Audiences} and visibility
|
17
|
+
# Each activity is attached to one or more {Relation relations}, which define
|
18
|
+
# the {SocialStream::Models::Subject subject} that can reach the activity
|
19
|
+
#
|
20
|
+
# In the case of a {Relation::Public public relation} everyone will be
|
21
|
+
# able to see the activity.
|
22
|
+
#
|
23
|
+
# In the case of {Relation::Custom custom relations}, only the subjects
|
24
|
+
# that have a {Tie} with that relation (in other words, the contacts that
|
25
|
+
# have been added as friends with that relation} will be able to reach the {Activity}
|
13
26
|
#
|
14
|
-
include NotificationsHelper
|
15
|
-
|
16
27
|
class Activity < ActiveRecord::Base
|
17
|
-
#
|
18
|
-
|
28
|
+
# FIXME: this does not follow the Rails way
|
29
|
+
include NotificationsHelper
|
19
30
|
|
20
31
|
# This has to be declared before 'has_ancestry' to work around rails issue #670
|
21
32
|
# See: https://github.com/rails/rails/issues/670
|
@@ -27,6 +38,13 @@ class Activity < ActiveRecord::Base
|
|
27
38
|
|
28
39
|
belongs_to :activity_verb
|
29
40
|
|
41
|
+
belongs_to :author,
|
42
|
+
:class_name => "Actor"
|
43
|
+
belongs_to :owner,
|
44
|
+
:class_name => "Actor"
|
45
|
+
belongs_to :user_author,
|
46
|
+
:class_name => "Actor"
|
47
|
+
|
30
48
|
has_many :audiences, :dependent => :destroy
|
31
49
|
has_many :relations, :through => :audiences
|
32
50
|
|
@@ -35,10 +53,26 @@ class Activity < ActiveRecord::Base
|
|
35
53
|
has_many :activity_objects,
|
36
54
|
:through => :activity_object_activities
|
37
55
|
|
56
|
+
scope :authored_by, lambda { |subject|
|
57
|
+
where(:author_id => Actor.normalize_id(subject))
|
58
|
+
}
|
59
|
+
scope :owned_by, lambda { |subject|
|
60
|
+
where(:owner_id => Actor.normalize_id(subject))
|
61
|
+
}
|
62
|
+
scope :authored_or_owned_by, lambda { |subjects|
|
63
|
+
ids = Actor.normalize_id(subjects)
|
64
|
+
|
65
|
+
where(arel_table[:author_id].in(ids).or(arel_table[:owner_id].in(ids)))
|
66
|
+
}
|
67
|
+
|
68
|
+
scope :shared_with, lambda { |subject|
|
69
|
+
joins(:audiences).
|
70
|
+
merge(Audience.where(:relation_id => Relation.ids_shared_with(subject)))
|
71
|
+
}
|
72
|
+
|
38
73
|
scope :wall, lambda { |args|
|
39
74
|
q =
|
40
75
|
select("DISTINCT activities.*").
|
41
|
-
joins(:channel).
|
42
76
|
joins(:audiences).
|
43
77
|
joins(:relations).
|
44
78
|
roots
|
@@ -48,14 +82,13 @@ class Activity < ActiveRecord::Base
|
|
48
82
|
where('activity_objects.object_type' => args[:object_type])
|
49
83
|
end
|
50
84
|
|
51
|
-
channels = Channel.arel_table
|
52
85
|
audiences = Audience.arel_table
|
53
86
|
relations = Relation.arel_table
|
54
87
|
|
55
88
|
owner_conditions =
|
56
|
-
|
57
|
-
or(
|
58
|
-
or(
|
89
|
+
arel_table[:author_id].eq(Actor.normalize_id(args[:owner])).
|
90
|
+
or(arel_table[:user_author_id].eq(Actor.normalize_id(args[:owner]))).
|
91
|
+
or(arel_table[:owner_id].eq(Actor.normalize_id(args[:owner])))
|
59
92
|
|
60
93
|
audience_conditions =
|
61
94
|
audiences[:relation_id].in(args[:relation_ids]).
|
@@ -65,16 +98,16 @@ class Activity < ActiveRecord::Base
|
|
65
98
|
case args[:type]
|
66
99
|
when :home
|
67
100
|
followed_conditions =
|
68
|
-
|
69
|
-
or(
|
101
|
+
arel_table[:author_id].in(args[:followed]).
|
102
|
+
or(arel_table[:owner_id].in(args[:followed]))
|
70
103
|
|
71
104
|
owner_conditions.
|
72
105
|
or(followed_conditions.and(audience_conditions))
|
73
106
|
when :profile
|
74
107
|
if args[:for].present?
|
75
108
|
visitor_conditions =
|
76
|
-
|
77
|
-
or(
|
109
|
+
arel_table[:author_id].eq(Actor.normalize_id(args[:for])).
|
110
|
+
or(arel_table[:owner_id].eq(Actor.normalize_id(args[:for])))
|
78
111
|
|
79
112
|
owner_conditions.
|
80
113
|
and(visitor_conditions.or(audience_conditions))
|
@@ -93,7 +126,7 @@ class Activity < ActiveRecord::Base
|
|
93
126
|
after_create :increment_like_count
|
94
127
|
after_destroy :decrement_like_count, :delete_notifications
|
95
128
|
|
96
|
-
validates_presence_of :relations
|
129
|
+
validates_presence_of :author_id, :user_author_id, :owner_id, :relations
|
97
130
|
|
98
131
|
#For now, it should be the last one
|
99
132
|
#FIXME
|
@@ -109,12 +142,37 @@ class Activity < ActiveRecord::Base
|
|
109
142
|
self.activity_verb = ActivityVerb[name]
|
110
143
|
end
|
111
144
|
|
145
|
+
# The {SocialStream::Models::Subject subject} author
|
146
|
+
def author_subject
|
147
|
+
author.subject
|
148
|
+
end
|
149
|
+
|
150
|
+
# The {SocialStream::Models::Subject subject} owner
|
151
|
+
def owner_subject
|
152
|
+
owner.subject
|
153
|
+
end
|
154
|
+
|
155
|
+
# The {SocialStream::Models::Subject subject} user actor
|
156
|
+
def user_author_subject
|
157
|
+
user_author.subject
|
158
|
+
end
|
159
|
+
|
160
|
+
# Does this {Activity} have the same sender and receiver?
|
161
|
+
def reflexive?
|
162
|
+
author_id == owner_id
|
163
|
+
end
|
164
|
+
|
165
|
+
# Is the author represented in this {Activity}?
|
166
|
+
def represented_author?
|
167
|
+
author_id != user_author_id
|
168
|
+
end
|
169
|
+
|
112
170
|
# The {Actor} author of this activity
|
113
171
|
#
|
114
172
|
# This method provides the {Actor}. Use {#sender_subject} for the {SocialStream::Models::Subject Subject}
|
115
173
|
# ({User}, {Group}, etc..)
|
116
174
|
def sender
|
117
|
-
|
175
|
+
author
|
118
176
|
end
|
119
177
|
|
120
178
|
# The {SocialStream::Models::Subject Subject} author of this activity
|
@@ -122,7 +180,7 @@ class Activity < ActiveRecord::Base
|
|
122
180
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
123
181
|
# Use {#sender} for the {Actor}.
|
124
182
|
def sender_subject
|
125
|
-
|
183
|
+
author_subject
|
126
184
|
end
|
127
185
|
|
128
186
|
# The wall where the activity is shown belongs to receiver
|
@@ -130,7 +188,7 @@ class Activity < ActiveRecord::Base
|
|
130
188
|
# This method provides the {Actor}. Use {#receiver_subject} for the {SocialStream::Models::Subject Subject}
|
131
189
|
# ({User}, {Group}, etc..)
|
132
190
|
def receiver
|
133
|
-
|
191
|
+
owner
|
134
192
|
end
|
135
193
|
|
136
194
|
# The wall where the activity is shown belongs to the receiver
|
@@ -138,7 +196,7 @@ class Activity < ActiveRecord::Base
|
|
138
196
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
139
197
|
# Use {#receiver} for the {Actor}.
|
140
198
|
def receiver_subject
|
141
|
-
|
199
|
+
owner_subject
|
142
200
|
end
|
143
201
|
|
144
202
|
# The comments about this activity
|
@@ -152,7 +210,7 @@ class Activity < ActiveRecord::Base
|
|
152
210
|
end
|
153
211
|
|
154
212
|
def liked_by(user) #:nodoc:
|
155
|
-
likes.
|
213
|
+
likes.authored_by(user)
|
156
214
|
end
|
157
215
|
|
158
216
|
# Does user like this activity?
|
@@ -162,12 +220,11 @@ class Activity < ActiveRecord::Base
|
|
162
220
|
|
163
221
|
# Build a new children activity where subject like this
|
164
222
|
def new_like(subject, user)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
:
|
170
|
-
:relation_ids => self.relation_ids
|
223
|
+
a = children.new :verb => "like",
|
224
|
+
:author_id => Actor.normalize_id(subject),
|
225
|
+
:user_author_id => Actor.normalize_id(user),
|
226
|
+
:owner_id => owner_id,
|
227
|
+
:relation_ids => self.relation_ids
|
171
228
|
|
172
229
|
if direct_activity_object.present?
|
173
230
|
a.activity_objects << direct_activity_object
|
@@ -218,7 +275,7 @@ class Activity < ActiveRecord::Base
|
|
218
275
|
participants.each do |p|
|
219
276
|
p.notify(notification_subject, "Youre not supposed to see this", self) unless p == sender
|
220
277
|
end
|
221
|
-
elsif ['like','follow','make-friend','post','update'].include? verb and !
|
278
|
+
elsif ['like','follow','make-friend','post','update'].include? verb and !reflexive?
|
222
279
|
receiver.notify(notification_subject, "Youre not supposed to see this", self)
|
223
280
|
end
|
224
281
|
true
|
@@ -241,15 +298,15 @@ class Activity < ActiveRecord::Base
|
|
241
298
|
|
242
299
|
# Is subject allowed to perform action on this {Activity}?
|
243
300
|
def allow?(subject, action)
|
244
|
-
return false if
|
301
|
+
return false if author.blank?
|
245
302
|
|
246
303
|
case action
|
247
304
|
when 'create'
|
248
|
-
return false if subject.blank? ||
|
305
|
+
return false if subject.blank? || author_id != Actor.normalize_id(subject)
|
249
306
|
|
250
307
|
rels = Relation.normalize(relation_ids)
|
251
308
|
|
252
|
-
own_rels = rels.select{ |r| r.actor_id ==
|
309
|
+
own_rels = rels.select{ |r| r.actor_id == author_id }
|
253
310
|
# Consider Relation::Single as own_relations
|
254
311
|
own_rels += rels.select{ |r| r.is_a?(Relation::Single) }
|
255
312
|
|
@@ -268,12 +325,12 @@ class Activity < ActiveRecord::Base
|
|
268
325
|
|
269
326
|
return false if subject.blank?
|
270
327
|
|
271
|
-
return true if [
|
328
|
+
return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
|
272
329
|
when 'update'
|
273
|
-
return true if [
|
330
|
+
return true if [author_id, owner_id].include?(Actor.normalize_id(subject))
|
274
331
|
when 'destroy'
|
275
332
|
# We only allow destroying to sender and receiver by now
|
276
|
-
return [
|
333
|
+
return [author_id, owner_id].include?(Actor.normalize_id(subject))
|
277
334
|
end
|
278
335
|
|
279
336
|
Relation.
|
@@ -298,6 +355,21 @@ class Activity < ActiveRecord::Base
|
|
298
355
|
allow?(subject, 'update')
|
299
356
|
end
|
300
357
|
|
358
|
+
# Is this activity public?
|
359
|
+
def public?
|
360
|
+
relation_ids.include? Relation::Public.instance.id
|
361
|
+
end
|
362
|
+
|
363
|
+
# The {Actor Actors} this activity is shared with
|
364
|
+
def audience
|
365
|
+
raise "Cannot get the audience of a public activity!" if public?
|
366
|
+
|
367
|
+
[ author, user_author, owner ].uniq |
|
368
|
+
Actor.
|
369
|
+
joins(:received_ties).
|
370
|
+
merge(Tie.where(:relation_id => relation_ids))
|
371
|
+
end
|
372
|
+
|
301
373
|
# The {Relation} with which activity is shared
|
302
374
|
def audience_in_words(subject, options = {})
|
303
375
|
options[:details] ||= :full
|
@@ -217,15 +217,7 @@ class ActivityObject < ActiveRecord::Base
|
|
217
217
|
|
218
218
|
@valid_relations = true
|
219
219
|
|
220
|
-
self.relation_ids =
|
221
|
-
if SocialStream.relation_model == :custom
|
222
|
-
owner.
|
223
|
-
relations.
|
224
|
-
allowing('read', 'activity').
|
225
|
-
map(&:id)
|
226
|
-
else
|
227
|
-
Array.wrap Relation::Public.instance.id
|
228
|
-
end
|
220
|
+
self.relation_ids = owner.activity_relation_ids
|
229
221
|
end
|
230
222
|
|
231
223
|
# validate method
|
data/app/models/actor.rb
CHANGED
@@ -73,16 +73,6 @@ class Actor < ActiveRecord::Base
|
|
73
73
|
has_many :relations,
|
74
74
|
:dependent => :destroy
|
75
75
|
|
76
|
-
has_many :authored_channels,
|
77
|
-
:class_name => "Channel",
|
78
|
-
:foreign_key => :author_id,
|
79
|
-
:dependent => :destroy
|
80
|
-
|
81
|
-
has_many :owned_channels,
|
82
|
-
:class_name => "Channel",
|
83
|
-
:foreign_key => :owner_id,
|
84
|
-
:dependent => :destroy
|
85
|
-
|
86
76
|
has_many :sent_actions,
|
87
77
|
:class_name => "ActivityAction",
|
88
78
|
:dependent => :destroy
|
@@ -328,11 +318,6 @@ class Actor < ActiveRecord::Base
|
|
328
318
|
ties_to(subject).with_permissions(action, object).any?
|
329
319
|
end
|
330
320
|
|
331
|
-
# The {Channel} of this {Actor} to self (totally close!)
|
332
|
-
def self_channel
|
333
|
-
Channel.find_or_create_by_author_id_and_user_author_id_and_owner_id id, id, id
|
334
|
-
end
|
335
|
-
|
336
321
|
# Return the {ActivityAction} model to an {ActivityObject}
|
337
322
|
def action_to(activity_object)
|
338
323
|
sent_actions.received_by(activity_object).first
|
@@ -391,12 +376,26 @@ class Actor < ActiveRecord::Base
|
|
391
376
|
any?
|
392
377
|
end
|
393
378
|
|
394
|
-
#
|
395
|
-
#
|
396
|
-
|
379
|
+
# The default {Relation Relations} for sharing an {Activity} owned
|
380
|
+
# by this {Actor}
|
381
|
+
def activity_relations
|
382
|
+
SocialStream.relation_model == :custom ?
|
383
|
+
relations.
|
384
|
+
allowing('read', 'activity') :
|
385
|
+
[ Relation::Public.instance ]
|
386
|
+
end
|
387
|
+
|
388
|
+
# The ids of the default {Relation Relations} for sharing an {Activity}
|
389
|
+
# owned by this {Actor}
|
390
|
+
def activity_relation_ids
|
391
|
+
activity_relations.map(&:id)
|
392
|
+
end
|
393
|
+
|
394
|
+
# This method returns all the {relations Relation} that subject can choose to broadcast an Activity in this {Actor}'s wall
|
397
395
|
#
|
396
|
+
# See {Activity} on how they can be shared with multiple {audicences Audience}, which corresponds to a {Relation}.
|
398
397
|
#
|
399
|
-
def
|
398
|
+
def activity_relations_for(subject, options = {})
|
400
399
|
if Actor.normalize(subject) == self
|
401
400
|
return relation_customs + Array.wrap(Relation::Public.instance)
|
402
401
|
else
|
@@ -404,9 +403,9 @@ class Actor < ActiveRecord::Base
|
|
404
403
|
end
|
405
404
|
end
|
406
405
|
|
407
|
-
# Are
|
408
|
-
def
|
409
|
-
activity_relations(
|
406
|
+
# Are {#activity_relations} available for subject?
|
407
|
+
def activity_relations_for?(subject, options = {})
|
408
|
+
activity_relations(subject, options).any?
|
410
409
|
end
|
411
410
|
|
412
411
|
# Is this {Actor} allowed to create a comment on activity?
|
@@ -459,37 +458,30 @@ class Actor < ActiveRecord::Base
|
|
459
458
|
# the wall for members of the group.
|
460
459
|
#
|
461
460
|
def wall(type, options = {})
|
462
|
-
|
463
|
-
|
464
|
-
args[:type] = type
|
465
|
-
args[:owner] = self
|
466
|
-
# Preserve this options
|
467
|
-
[ :for, :object_type ].each do |opt|
|
468
|
-
args[opt] = options[opt]
|
469
|
-
end
|
461
|
+
options[:for] = self if type == :home
|
470
462
|
|
471
|
-
|
472
|
-
|
473
|
-
|
463
|
+
wall =
|
464
|
+
Activity.
|
465
|
+
select("DISTINCT activities.*").
|
466
|
+
roots.
|
467
|
+
includes(:author, :user_author, :owner, :activity_objects, :activity_verb, :relations)
|
474
468
|
|
475
|
-
|
476
|
-
args[:relation_ids] =
|
469
|
+
actor_ids =
|
477
470
|
case type
|
478
471
|
when :home
|
479
|
-
|
480
|
-
Relation.allow(self, 'read', 'activity').map(&:id)
|
472
|
+
following_actor_and_self_ids
|
481
473
|
when :profile
|
482
|
-
|
483
|
-
#
|
484
|
-
# The relations that can be read by options[:for]
|
485
|
-
options[:for].present? ?
|
486
|
-
Relation.allow(options[:for], 'read', 'activity').map(&:id) :
|
487
|
-
[]
|
474
|
+
id
|
488
475
|
else
|
489
476
|
raise "Unknown type of wall: #{ type }"
|
490
477
|
end
|
491
478
|
|
492
|
-
|
479
|
+
wall = wall.authored_or_owned_by(actor_ids)
|
480
|
+
|
481
|
+
# Authentication
|
482
|
+
wall = wall.shared_with(options[:for])
|
483
|
+
|
484
|
+
wall = wall.order("created_at desc")
|
493
485
|
end
|
494
486
|
|
495
487
|
def logo
|
@@ -507,7 +499,7 @@ class Actor < ActiveRecord::Base
|
|
507
499
|
end
|
508
500
|
|
509
501
|
def liked_by(subject) #:nodoc:
|
510
|
-
likes.
|
502
|
+
likes.authored_by(subject)
|
511
503
|
end
|
512
504
|
|
513
505
|
# Does subject like this {Actor}?
|
@@ -517,14 +509,11 @@ class Actor < ActiveRecord::Base
|
|
517
509
|
|
518
510
|
# Build a new activity where subject like this
|
519
511
|
def new_like(subject, user)
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
a = Activity.new :verb => "like",
|
526
|
-
:channel => channel,
|
527
|
-
:relation_ids => Array(Relation::Public.instance.id)
|
512
|
+
a = Activity.new :verb => "like",
|
513
|
+
:author_id => Actor.normalize_id(subject),
|
514
|
+
:user_author_id => Actor.normalize_id(user),
|
515
|
+
:owner_id => id,
|
516
|
+
:relation_ids => Array(Relation::Public.instance.id)
|
528
517
|
|
529
518
|
a.activity_objects << activity_object
|
530
519
|
|
data/app/models/contact.rb
CHANGED
@@ -164,27 +164,6 @@ class Contact < ActiveRecord::Base
|
|
164
164
|
end
|
165
165
|
end
|
166
166
|
|
167
|
-
# The related {Channel} to this {Contact}.
|
168
|
-
#
|
169
|
-
# If the sender of this {Contact} is a user, the {Channel} is defined. If it is
|
170
|
-
# other kind of {SocialStream::Models::Subject}, the {Channel#user_author} must
|
171
|
-
# be provided.
|
172
|
-
def channel(user = nil)
|
173
|
-
user_id =
|
174
|
-
if sender.subject_type == "User"
|
175
|
-
sender_id
|
176
|
-
elsif user.present? && Actor.normalize(user).subject_type == "User"
|
177
|
-
Actor.normalize_id(user)
|
178
|
-
else
|
179
|
-
raise "Invalid channel user_author: #{ user.inspect }"
|
180
|
-
end
|
181
|
-
|
182
|
-
Channel.
|
183
|
-
find_or_create_by_author_id_and_user_author_id_and_owner_id sender_id,
|
184
|
-
user_id,
|
185
|
-
receiver_id
|
186
|
-
end
|
187
|
-
|
188
167
|
private
|
189
168
|
|
190
169
|
def build_user_author
|
data/app/models/tie.rb
CHANGED
@@ -146,7 +146,7 @@ class Tie < ActiveRecord::Base
|
|
146
146
|
Activity.create! :author => contact.sender,
|
147
147
|
:user_author => contact.user_author,
|
148
148
|
:owner => contact.receiver,
|
149
|
-
:relation_ids => contact.
|
149
|
+
:relation_ids => contact.receiver.activity_relation_ids,
|
150
150
|
:activity_verb => ActivityVerb[contact.verb]
|
151
151
|
end
|
152
152
|
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<%= javascript_tag do %>
|
22
22
|
var relation_public = <%= Relation::Public.instance.id %>;
|
23
23
|
var public_selected = false;
|
24
|
-
var relation_options = <%= escape_javascript(current_subject.
|
24
|
+
var relation_options = <%= escape_javascript(current_subject.activity_relations_for(receiver).sort.map{ |r| r.id }.to_json) %>;
|
25
25
|
var relation_public_pos = 0;
|
26
26
|
for(id in relation_options){
|
27
27
|
if(relation_options[id]==relation_public){
|
@@ -32,7 +32,7 @@
|
|
32
32
|
}
|
33
33
|
//For security with check "var default_security_width = '100px';" in activities.js.erb
|
34
34
|
<% end %>
|
35
|
-
<%= select_tag :relation_ids, options_for_select(current_subject.
|
35
|
+
<%= select_tag :relation_ids, options_for_select(current_subject.activity_relations_for(receiver).sort.map{ |r| [ r.name, r.id ] }), :id => 'security', :multiple => true, :title => t("activity.privacy.myself.contacts.#{ receiver.class.to_s.underscore }") %>
|
36
36
|
<% else %>
|
37
37
|
<div id="security_chzn" class="chzn-container chzn-container-multi">
|
38
38
|
<ul class="chzn-choices">
|
@@ -8,11 +8,17 @@
|
|
8
8
|
|
9
9
|
<% if user_signed_in? %>
|
10
10
|
·
|
11
|
-
<%= link_to activity.audience_in_words(current_subject, :details => :summary),
|
11
|
+
<%= link_to image_tag("btn/#{ activity.public? ? 'public' : 'restricted' }.png", :class => 'menu_icon') + activity.audience_in_words(current_subject, :details => :summary),
|
12
12
|
'javascript:;',
|
13
13
|
:class => 'activity_audience_summary' %>
|
14
14
|
<div class="activity_audience">
|
15
15
|
<%= activity.audience_in_words(current_subject) %>
|
16
|
+
<% unless activity.public? %>
|
17
|
+
·
|
18
|
+
<%= link_to t('activity.audience.show'), audience_path(:activity_id => activity.id), :remote => true %>
|
19
|
+
<div class="activity-audience-list-<%= activity.id %>">
|
20
|
+
</div>
|
21
|
+
<% end %>
|
16
22
|
</div>
|
17
23
|
<% end %>
|
18
24
|
|
@@ -0,0 +1 @@
|
|
1
|
+
$('.activity-audience-list-<%= @activity.id %>').html('<%= j render(:partial => 'list') %>');
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -86,6 +86,8 @@ Rails.application.routes.draw do
|
|
86
86
|
resources :activities do
|
87
87
|
resource :like
|
88
88
|
end
|
89
|
+
|
90
|
+
get 'audience/index', :as => :audience
|
89
91
|
|
90
92
|
match 'cheesecake' => 'cheesecake#index', :as => :cheesecake
|
91
93
|
match 'update_cheesecake' => 'cheesecake#update', :as => :update_cheesecake
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class RemoveActivityChannels < ActiveRecord::Migration
|
2
|
+
class Channel < ActiveRecord::Base; end
|
3
|
+
|
4
|
+
def up
|
5
|
+
change_table :activities do |t|
|
6
|
+
t.references :author
|
7
|
+
t.references :user_author
|
8
|
+
t.references :owner
|
9
|
+
end
|
10
|
+
|
11
|
+
Activity.record_timestamps = false
|
12
|
+
Activity.reset_column_information
|
13
|
+
|
14
|
+
Activity.all.each do |a|
|
15
|
+
c = Channel.find a.channel_id
|
16
|
+
%w{ author_id user_author_id owner_id }.each do |m|
|
17
|
+
a.__send__ "#{ m }=", c.__send__(m) # a.author_id = c.author_id
|
18
|
+
end
|
19
|
+
a.save!
|
20
|
+
end
|
21
|
+
|
22
|
+
Activity.record_timestamps = true
|
23
|
+
|
24
|
+
remove_foreign_key :activities, :name => 'index_activities_on_channel_id'
|
25
|
+
remove_column :activities, :channel_id
|
26
|
+
|
27
|
+
Activity.reset_column_information
|
28
|
+
|
29
|
+
drop_table :channels
|
30
|
+
end
|
31
|
+
|
32
|
+
def down
|
33
|
+
raise ActiveRecord::IrreversibleMigration
|
34
|
+
end
|
35
|
+
end
|
@@ -20,7 +20,6 @@ module SocialStream
|
|
20
20
|
|
21
21
|
initializer "social_stream-base.model.supertypes" do
|
22
22
|
ActiveSupport.on_load(:active_record) do
|
23
|
-
include SocialStream::Models::Channeled::ActiveRecord
|
24
23
|
include SocialStream::Models::Subtype::ActiveRecord
|
25
24
|
include SocialStream::Models::Supertype::ActiveRecord
|
26
25
|
end
|
data/lib/social_stream-base.rb
CHANGED
data/lib/tasks/db/populate.rake
CHANGED
@@ -112,14 +112,16 @@ namespace :db do
|
|
112
112
|
ties_start = Time.now
|
113
113
|
|
114
114
|
@available_actors.each do |a|
|
115
|
-
actors = @available_actors.dup
|
116
|
-
|
117
|
-
|
115
|
+
actors = @available_actors.dup
|
116
|
+
actors.delete(a)
|
117
|
+
|
118
|
+
relations = a.relation_customs + [ Relation::Reject.instance ]
|
119
|
+
|
118
120
|
Forgery::Basic.number(:at_most => actors.size).times do
|
119
121
|
actor = actors.delete_at((rand * actors.size).to_i)
|
120
122
|
contact = a.contact_to!(actor)
|
121
123
|
contact.user_author = a.user_author if a.subject_type != "User"
|
122
|
-
contact.relation_ids =
|
124
|
+
contact.relation_ids = [ Forgery::Extensions::Array.new(relations).random.id ]
|
123
125
|
end
|
124
126
|
end
|
125
127
|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe AudienceController do
|
4
|
+
include SocialStream::TestHelpers
|
5
|
+
include SocialStream::TestHelpers::Controllers
|
6
|
+
|
7
|
+
render_views
|
8
|
+
|
9
|
+
context "with activity" do
|
10
|
+
before :all do
|
11
|
+
@activity = Factory(:activity)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should not be redered to public" do
|
15
|
+
get :index, :activity_id => @activity.id, :format => :js
|
16
|
+
|
17
|
+
response.should redirect_to(:new_user_session)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should not be rendered to anyone" do
|
21
|
+
sign_in Factory(:user)
|
22
|
+
|
23
|
+
begin
|
24
|
+
get :index, :activity_id => @activity.id, :format => :js
|
25
|
+
|
26
|
+
assert false
|
27
|
+
rescue CanCan::AccessDenied
|
28
|
+
assert true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not be rendered to author" do
|
33
|
+
sign_in @activity.author_subject
|
34
|
+
|
35
|
+
get :index, :activity_id => @activity.id, :format => :js
|
36
|
+
|
37
|
+
response.should be_success
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -13,7 +13,7 @@ describe CommentsController do
|
|
13
13
|
|
14
14
|
describe "comment from user" do
|
15
15
|
before do
|
16
|
-
activity = Factory(:self_activity, :
|
16
|
+
activity = Factory(:self_activity, :author => @user.actor)
|
17
17
|
|
18
18
|
model_attributes[:author_id] = @user.actor_id
|
19
19
|
model_attributes[:owner_id] = @user.actor_id
|
@@ -38,7 +38,7 @@ describe CommentsController do
|
|
38
38
|
describe "comment to friend" do
|
39
39
|
before do
|
40
40
|
f = Factory(:friend, :contact => Factory(:contact, :receiver => @user.actor)).sender
|
41
|
-
activity = Factory(:self_activity, :
|
41
|
+
activity = Factory(:self_activity, :author => f)
|
42
42
|
|
43
43
|
model_attributes[:author_id] = @user.actor_id
|
44
44
|
model_attributes[:owner_id] = f.id
|
@@ -52,7 +52,7 @@ describe CommentsController do
|
|
52
52
|
describe "post to acquaintance" do
|
53
53
|
before do
|
54
54
|
a = Factory(:acquaintance, :contact => Factory(:contact, :receiver => @user.actor)).sender
|
55
|
-
activity = Factory(:self_activity, :
|
55
|
+
activity = Factory(:self_activity, :author => a)
|
56
56
|
|
57
57
|
model_attributes[:author_id] = @user.actor_id
|
58
58
|
model_attributes[:owner_id] = a.id
|
data/spec/factories/activity.rb
CHANGED
@@ -23,9 +23,11 @@ end
|
|
23
23
|
## End of helpers
|
24
24
|
|
25
25
|
Factory.define :activity do |a|
|
26
|
-
a.
|
26
|
+
a.author { Factory(:user).actor }
|
27
|
+
a.user_author { |b| b.author }
|
28
|
+
a.owner { |b| Factory(:friend, :contact => Factory(:contact, :receiver => b.author)).sender }
|
27
29
|
a.activity_verb { ActivityVerb["post"] }
|
28
|
-
a.relation_ids { |b|
|
30
|
+
a.relation_ids { |b| [ b.owner.relation_custom('friend').id ] }
|
29
31
|
a.activity_object_ids { |b|
|
30
32
|
# Create post
|
31
33
|
post = Factory(:post,
|
@@ -40,8 +42,10 @@ Factory.define :activity do |a|
|
|
40
42
|
end
|
41
43
|
|
42
44
|
Factory.define :self_activity, :parent => :activity do |a|
|
43
|
-
a.
|
44
|
-
a.
|
45
|
+
a.author { Factory(:user).actor }
|
46
|
+
a.user_author { |b| b.author }
|
47
|
+
a.owner { |b| b.author }
|
48
|
+
a.relation_ids { |b| [ b.author.relation_custom('friend').id ] }
|
45
49
|
a.activity_object_ids { |b|
|
46
50
|
# Create post
|
47
51
|
post = Factory(:post,
|
@@ -63,10 +67,12 @@ end
|
|
63
67
|
|
64
68
|
Factory.define :like_activity, :class => 'Activity' do |a|
|
65
69
|
a.association :parent, :factory => :activity
|
66
|
-
a.
|
70
|
+
a.author { |b| Factory(:friend, :sender => b.parent.owner).receiver }
|
71
|
+
a.user_author { |b| b.author }
|
72
|
+
a.owner { |b| b.parent.owner }
|
67
73
|
a.activity_verb { ActivityVerb["like"] }
|
68
74
|
a.relation_ids { |b| b.parent.relation_ids }
|
69
|
-
a.after_build{ |b| b.activity_object_ids = b.parent.activity_object_ids }
|
75
|
+
a.after_build { |b| b.activity_object_ids = b.parent.activity_object_ids }
|
70
76
|
end
|
71
77
|
|
72
78
|
|
data/spec/models/tie_spec.rb
CHANGED
@@ -41,8 +41,9 @@ describe Tie do
|
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should create activity with follow verb" do
|
44
|
-
@tie.
|
45
|
-
|
44
|
+
activity = Activity.authored_by(@tie.sender).owned_by(@tie.receiver).first
|
45
|
+
activity.should be_present
|
46
|
+
activity.verb.should eq('follow')
|
46
47
|
end
|
47
48
|
|
48
49
|
context "reciprocal" do
|
@@ -51,8 +52,10 @@ describe Tie do
|
|
51
52
|
end
|
52
53
|
|
53
54
|
it "should create activity with make-friend verb" do
|
54
|
-
@reciprocal.
|
55
|
-
|
55
|
+
activity = Activity.authored_by(@reciprocal.sender).owned_by(@reciprocal.receiver).first
|
56
|
+
|
57
|
+
activity.should be_present
|
58
|
+
activity.verb.should eq('make-friend')
|
56
59
|
end
|
57
60
|
end
|
58
61
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: social_stream-base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2012-05-
|
13
|
+
date: 2012-05-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: deep_merge
|
@@ -596,7 +596,6 @@ files:
|
|
596
596
|
- app/assets/images/btn/btn_profile.png
|
597
597
|
- app/assets/images/btn/btn_rank.png
|
598
598
|
- app/assets/images/btn/btn_read.png
|
599
|
-
- app/assets/images/btn/btn_security.png
|
600
599
|
- app/assets/images/btn/btn_send.png
|
601
600
|
- app/assets/images/btn/btn_spam.png
|
602
601
|
- app/assets/images/btn/btn_star.png
|
@@ -636,6 +635,8 @@ files:
|
|
636
635
|
- app/assets/images/btn/point_blue.png
|
637
636
|
- app/assets/images/btn/point_gray.png
|
638
637
|
- app/assets/images/btn/post.png
|
638
|
+
- app/assets/images/btn/public.png
|
639
|
+
- app/assets/images/btn/restricted.png
|
639
640
|
- app/assets/images/btn/search.png
|
640
641
|
- app/assets/images/btn/search_icon.png
|
641
642
|
- app/assets/images/btn/shadow.png
|
@@ -770,6 +771,7 @@ files:
|
|
770
771
|
- app/controllers/activities_controller.rb
|
771
772
|
- app/controllers/activity_actions_controller.rb
|
772
773
|
- app/controllers/api_controller.rb
|
774
|
+
- app/controllers/audience_controller.rb
|
773
775
|
- app/controllers/authentications_controller.rb
|
774
776
|
- app/controllers/cheesecake_controller.rb
|
775
777
|
- app/controllers/comments_controller.rb
|
@@ -821,7 +823,6 @@ files:
|
|
821
823
|
- app/models/actor.rb
|
822
824
|
- app/models/audience.rb
|
823
825
|
- app/models/authentication.rb
|
824
|
-
- app/models/channel.rb
|
825
826
|
- app/models/comment.rb
|
826
827
|
- app/models/contact.rb
|
827
828
|
- app/models/group.rb
|
@@ -858,6 +859,8 @@ files:
|
|
858
859
|
- app/views/actors/_actor.html.erb
|
859
860
|
- app/views/actors/_actor_cheesecake.html.erb
|
860
861
|
- app/views/api/activity_atom_feed.atom.builder
|
862
|
+
- app/views/audience/_list.html.erb
|
863
|
+
- app/views/audience/index.js.erb
|
861
864
|
- app/views/avatars/index.html.erb
|
862
865
|
- app/views/avatars/update.js.erb
|
863
866
|
- app/views/cheesecake/_cheesecake.html.erb
|
@@ -1055,6 +1058,7 @@ files:
|
|
1055
1058
|
- db/migrate/20120403175913_create_activity_object_audiences.rb
|
1056
1059
|
- db/migrate/20120411132550_add_visit_count_to_activity_object.rb
|
1057
1060
|
- db/migrate/20120411151413_relation_public_permissions.rb
|
1061
|
+
- db/migrate/20120526171311_remove_activity_channels.rb
|
1058
1062
|
- lib/acts_as_taggable_on/acts_as_taggable_on/dirty.rb
|
1059
1063
|
- lib/acts_as_taggable_on/social_stream.rb
|
1060
1064
|
- lib/generators/social_stream/base/install_generator.rb
|
@@ -1109,7 +1113,6 @@ files:
|
|
1109
1113
|
- lib/social_stream/d3.rb
|
1110
1114
|
- lib/social_stream/migrations/base.rb
|
1111
1115
|
- lib/social_stream/migrations/components.rb
|
1112
|
-
- lib/social_stream/models/channeled.rb
|
1113
1116
|
- lib/social_stream/models/object.rb
|
1114
1117
|
- lib/social_stream/models/subject.rb
|
1115
1118
|
- lib/social_stream/models/subtype.rb
|
@@ -1132,6 +1135,7 @@ files:
|
|
1132
1135
|
- lib/tasks/workers.rake
|
1133
1136
|
- lib/thinking-sphinx/social_stream.rb
|
1134
1137
|
- social_stream-base.gemspec
|
1138
|
+
- spec/controllers/audience_controller_spec.rb
|
1135
1139
|
- spec/controllers/comments_controller_spec.rb
|
1136
1140
|
- spec/controllers/contacts_controller_spec.rb
|
1137
1141
|
- spec/controllers/followers_controller_spec.rb
|
Binary file
|
data/app/models/channel.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# A {Channel} is the union of the three {Actors} that are involved in an {Activity}:
|
2
|
-
#
|
3
|
-
# * The author that creates a post, comment, etc. This can be a {User}, {Group}
|
4
|
-
# or any kind of {SocialStream::Models::Subject subject}
|
5
|
-
# * The user_author representing the author. When users change session and
|
6
|
-
# act in behalf of a {Group}, Social Stream still records which user is responsible
|
7
|
-
# for an {Activity}
|
8
|
-
# * The owner in whose wall the Activity is performed.
|
9
|
-
#
|
10
|
-
class Channel < ActiveRecord::Base
|
11
|
-
# Author can be any type of Actor: User, Group, etc.
|
12
|
-
belongs_to :author,
|
13
|
-
:class_name => "Actor"
|
14
|
-
# Owner is the wall's subject this object is posted to
|
15
|
-
belongs_to :owner,
|
16
|
-
:class_name => "Actor"
|
17
|
-
|
18
|
-
# UserAuthor is the real user behind the Author
|
19
|
-
belongs_to :user_author,
|
20
|
-
:class_name => "Actor"
|
21
|
-
|
22
|
-
has_many :activities, :dependent => :destroy
|
23
|
-
|
24
|
-
validates_uniqueness_of :author_id, :scope => [ :owner_id, :user_author_id ]
|
25
|
-
validates_uniqueness_of :owner_id, :scope => [ :author_id, :user_author_id ]
|
26
|
-
validates_uniqueness_of :user_author_id, :scope => [ :author_id, :owner_id ]
|
27
|
-
|
28
|
-
scope :authored_by, lambda { |subject|
|
29
|
-
id = Actor.normalize_id subject
|
30
|
-
|
31
|
-
where(arel_table[:author_id].eq(id).or(arel_table[:user_author_id].eq(id)))
|
32
|
-
}
|
33
|
-
|
34
|
-
scope :subject_authored_by, lambda { |subject|
|
35
|
-
id = Actor.normalize_id subject
|
36
|
-
|
37
|
-
where(:author_id => id)
|
38
|
-
}
|
39
|
-
|
40
|
-
# The {SocialStream::Models::Subject subject} author
|
41
|
-
def author_subject
|
42
|
-
author.subject
|
43
|
-
end
|
44
|
-
|
45
|
-
# The {SocialStream::Models::Subject subject} owner
|
46
|
-
def owner_subject
|
47
|
-
owner.subject
|
48
|
-
end
|
49
|
-
|
50
|
-
# The {SocialStream::Models::Subject subject} user actor
|
51
|
-
def user_author_subject
|
52
|
-
user_author.subject
|
53
|
-
end
|
54
|
-
|
55
|
-
# Does this {Channel} have the same sender and receiver?
|
56
|
-
def reflexive?
|
57
|
-
author_id == owner_id
|
58
|
-
end
|
59
|
-
|
60
|
-
# Is the author represented in this {Channel}?
|
61
|
-
def represented_author?
|
62
|
-
author_id != user_author_id
|
63
|
-
end
|
64
|
-
end
|
@@ -1,56 +0,0 @@
|
|
1
|
-
module SocialStream
|
2
|
-
module Models
|
3
|
-
# Models that have author, user_author and owner, properties saved in {Channel}.
|
4
|
-
# Currently {Activity} and {ActivityObject}
|
5
|
-
module Channeled
|
6
|
-
# Add the method {#channeled} to ActiveRecord
|
7
|
-
module ActiveRecord
|
8
|
-
extend ActiveSupport::Concern
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
# This class is channeled. See {Channel}
|
12
|
-
def channeled
|
13
|
-
include SocialStream::Models::Channeled
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
extend ActiveSupport::Concern
|
19
|
-
|
20
|
-
included do
|
21
|
-
# Channeled models are subtypes of {Channel}
|
22
|
-
# Author, owner and user_author are defined in its channel
|
23
|
-
subtype_of :channel,
|
24
|
-
:belongs => { :dependent => nil }
|
25
|
-
|
26
|
-
# before_validation :set_owner_id, :on => :create
|
27
|
-
|
28
|
-
before_validation :check_existing_channel
|
29
|
-
end
|
30
|
-
|
31
|
-
protected
|
32
|
-
|
33
|
-
# Use existing channel, do not create a new one
|
34
|
-
def check_existing_channel
|
35
|
-
return unless channel!.new_record?
|
36
|
-
|
37
|
-
existing_channel =
|
38
|
-
Channel.
|
39
|
-
where(:author_id => author_id,
|
40
|
-
:owner_id => owner_id,
|
41
|
-
:user_author_id => user_author_id).
|
42
|
-
first
|
43
|
-
|
44
|
-
return if existing_channel.blank?
|
45
|
-
|
46
|
-
self.channel = existing_channel
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def set_owner_id
|
52
|
-
self.owner_id ||= author_id
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|