social_stream-base 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/flags/en.png +0 -0
- data/app/assets/images/flags/es.png +0 -0
- data/app/assets/javascripts/toolbar.js +22 -1
- data/app/assets/stylesheets/activities.css.scss +1 -1
- data/app/assets/stylesheets/cheesecake.css.scss +46 -4
- data/app/assets/stylesheets/settings.css +11 -0
- data/app/controllers/cheesecake_controller.rb +15 -3
- data/app/controllers/contacts_controller.rb +2 -0
- data/app/controllers/conversations_controller.rb +5 -5
- data/app/controllers/likes_controller.rb +1 -1
- data/app/helpers/notifications_helper.rb +10 -0
- data/app/models/activity.rb +55 -36
- data/app/models/activity_object.rb +3 -23
- data/app/models/actor.rb +20 -4
- data/app/models/channel.rb +13 -1
- data/app/models/comment.rb +4 -0
- data/app/models/contact.rb +55 -19
- data/app/models/group.rb +5 -2
- data/app/models/like.rb +2 -2
- data/app/models/relation/custom.rb +1 -1
- data/app/models/tie.rb +4 -3
- data/app/views/cheesecake/_cheesecake.html.erb +63 -0
- data/app/views/cheesecake/_index.html.erb +43 -86
- data/app/views/cheesecake/index.html.erb +2 -0
- data/app/views/cheesecake/update.js.erb +3 -0
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/registrations/new.html.erb +1 -1
- data/app/views/devise/sessions/new.html.erb +1 -1
- data/app/{assets/stylesheets/0_devise_sign.css → views/layouts/_devise_style.html.erb} +3 -1
- data/app/views/layouts/_header_signed_in.erb +1 -1
- data/app/views/message_mailer/new_message_email.html.erb +2 -1
- data/app/views/message_mailer/new_message_email.text.erb +2 -1
- data/app/views/message_mailer/reply_message_email.html.erb +2 -1
- data/app/views/message_mailer/reply_message_email.text.erb +2 -1
- data/app/views/notification_mailer/new_notification_email.html.erb +2 -1
- data/app/views/notification_mailer/new_notification_email.text.erb +2 -1
- data/app/views/notifications/activities/_post.html.erb +24 -1
- data/app/views/notifications/activities/_post.text.erb +22 -3
- data/app/views/settings/_language.html.erb +1 -1
- data/config/locales/en.yml +3 -2
- data/config/locales/es.yml +4 -3
- data/config/routes.rb +1 -0
- data/db/migrate/20120111141717_activity_channels.rb +74 -0
- data/lib/social_stream-base.rb +1 -0
- data/lib/social_stream/base/engine.rb +2 -1
- data/lib/social_stream/base/version.rb +1 -1
- data/lib/social_stream/models/channeled.rb +50 -0
- data/lib/social_stream/models/object.rb +4 -13
- data/lib/social_stream/toolbar_config/base.rb +1 -1
- data/lib/tasks/db/populate.rake +1 -1
- data/social_stream-base.gemspec +2 -2
- data/spec/controllers/comments_controller_spec.rb +3 -3
- data/spec/factories/activity.rb +3 -3
- data/spec/factories/contact.rb +2 -0
- data/spec/models/activity_authorization_spec.rb +5 -1
- data/spec/models/like_spec.rb +3 -3
- data/spec/models/tie_spec.rb +4 -4
- metadata +70 -64
- data/vendor/assets/javascripts/menu.js +0 -25
Binary file
|
Binary file
|
@@ -1 +1,22 @@
|
|
1
|
-
|
1
|
+
function initMenu() {
|
2
|
+
$('.toolbar_menu ul li ul').hide();
|
3
|
+
$('.toolbar_menu li a').click( function() {
|
4
|
+
$(this).next().slideToggle('normal');
|
5
|
+
}
|
6
|
+
);
|
7
|
+
//Logo menu for current subject
|
8
|
+
//Full Caption Sliding (Hidden to Visible)
|
9
|
+
$('.logo_grid.logo_full').hover( function() {
|
10
|
+
$(".logo_menu", this).stop().animate({top:'101px'},{queue:false,duration:160});
|
11
|
+
}, function() {
|
12
|
+
$(".logo_menu", this).stop().animate({top:'1119px'},{queue:false,duration:160});
|
13
|
+
});
|
14
|
+
}
|
15
|
+
|
16
|
+
function expandSubMenu(id) {
|
17
|
+
$('#' + id + '_menu').next().show();
|
18
|
+
}
|
19
|
+
|
20
|
+
$(document).ready(function() {
|
21
|
+
initMenu();
|
22
|
+
});
|
@@ -33,7 +33,7 @@
|
|
33
33
|
.super_activity{width: 95%;}
|
34
34
|
.activity { text-align:left; display: block; vertical-align: top; padding: 10px 0px 5px 0px;
|
35
35
|
display: inline-block; color: $sentence-color; font-size: 13px; color: $main-color;border-bottom:1px solid #E9E9E9;}
|
36
|
-
.actor_logo { width: 38px; padding:
|
36
|
+
.actor_logo { width: 38px; padding: 0px 0px 5px 5px; display: inline-block; vertical-align: top;}
|
37
37
|
.activity_content { padding: 0px; display: inline-block; color: $sentence-color; width: 89%; word-wrap: break-word; }
|
38
38
|
.actor_name {font-size: 13px;}
|
39
39
|
.actor_name a{font-weight: bold;}
|
@@ -3,11 +3,13 @@
|
|
3
3
|
#cheesecake {
|
4
4
|
position: relative;
|
5
5
|
padding: 20px;
|
6
|
+
padding-top: 0px;
|
6
7
|
}
|
7
8
|
#contacts_cheesecake {
|
8
9
|
width: 440px;
|
9
10
|
height: 440px;
|
10
|
-
padding: 0px;
|
11
|
+
padding: 0px;
|
12
|
+
margin-top: 45px;
|
11
13
|
float: left;
|
12
14
|
}
|
13
15
|
#contacts_filter {
|
@@ -39,19 +41,59 @@
|
|
39
41
|
}
|
40
42
|
#contacts_grid_extra {
|
41
43
|
width: 270px;
|
42
|
-
padding: 5px;
|
43
|
-
height: 10px;
|
44
|
-
border: solid 1px $input-border-color;
|
45
44
|
text-align: center;
|
46
45
|
float: right;
|
47
46
|
margin-right: 20px;
|
48
47
|
cursor: pointer;
|
48
|
+
vertical-align: middle;
|
49
|
+
padding-top: 6px;
|
50
|
+
background: #DEEFF8;
|
51
|
+
padding-left: 10px;
|
52
|
+
display: block;
|
53
|
+
height: 20px;
|
54
|
+
font-weight: bold;
|
55
|
+
}
|
56
|
+
#contacts_save {
|
57
|
+
width: 270px;
|
58
|
+
padding-right: 5px;
|
59
|
+
height: 25px;
|
60
|
+
text-align: right;
|
61
|
+
float: right;
|
62
|
+
margin-right: 20px;
|
63
|
+
}
|
64
|
+
#contacts_save_form {
|
65
|
+
overflow: visible;
|
66
|
+
}
|
67
|
+
#contacts_changes {
|
68
|
+
width: 705px;
|
69
|
+
margin-left: 20px;
|
70
|
+
}
|
71
|
+
#contacts_changes_title {
|
72
|
+
vertical-align: middle;
|
73
|
+
padding-top: 6px;
|
74
|
+
background: $secondary-color;
|
75
|
+
padding-left: 10px;
|
76
|
+
display: block;
|
77
|
+
height: 20px;
|
78
|
+
font-weight: bold;
|
79
|
+
cursor: pointer;
|
80
|
+
}
|
81
|
+
#contacts_changes_details {
|
82
|
+
border: solid 1px $secondary-color;
|
83
|
+
border-top: 0px;
|
84
|
+
padding: 5px;
|
85
|
+
display: none;
|
86
|
+
max-height: 200px;
|
87
|
+
}
|
88
|
+
#contacts_changes_details ul{
|
89
|
+
padding-left: 20px;
|
49
90
|
}
|
50
91
|
#contacts_grid .actor {
|
51
92
|
width: 48px;
|
52
93
|
height: 48px;
|
53
94
|
float: left;
|
54
95
|
margin: 4px;
|
96
|
+
display: none;
|
55
97
|
}
|
56
98
|
#contacts_grid .actor.focused {
|
57
99
|
border: 2px solid $main-color;
|
@@ -3,6 +3,17 @@
|
|
3
3
|
display:block;
|
4
4
|
padding-left:10px;
|
5
5
|
}
|
6
|
+
select#language {
|
7
|
+
background: #fff;
|
8
|
+
}
|
9
|
+
select#language option {
|
10
|
+
padding: 3px 0 3px 30px;
|
11
|
+
background-repeat: no-repeat;
|
12
|
+
background-position: 3px center;
|
13
|
+
}
|
14
|
+
select#language option[value=browser] { padding-left: 0; }
|
15
|
+
select#language option[value=en] { background-image: url(flags/en.png); }
|
16
|
+
select#language option[value=es] { background-image: url(flags/es.png); }
|
6
17
|
#api_token {
|
7
18
|
font-weight: bold;
|
8
19
|
font-style: italic;
|
@@ -1,9 +1,21 @@
|
|
1
1
|
class CheesecakeController < ApplicationController
|
2
|
-
|
2
|
+
|
3
3
|
before_filter :authenticate_user!
|
4
|
-
|
5
4
|
def index
|
6
5
|
@actors = current_subject.contact_actors(:direction => :sent)
|
7
6
|
end
|
8
|
-
|
7
|
+
|
8
|
+
def update
|
9
|
+
changes = JSON.parse params[:contacts_save_changes] if params[:contacts_save_changes].is_a? String
|
10
|
+
|
11
|
+
if (actors = changes["actors"]).present? and actors.is_a? Array
|
12
|
+
actors.each do |actor|
|
13
|
+
next if (contact = Contact.find_by_id(actor["extraInfo"].to_i)).nil?
|
14
|
+
contact.relation_ids = actor["subsectors"]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
@actors = current_subject.contact_actors(:direction => :sent)
|
19
|
+
end
|
20
|
+
|
9
21
|
end
|
@@ -24,6 +24,8 @@ class ContactsController < ApplicationController
|
|
24
24
|
params[:contact][:relation_ids].present? &&
|
25
25
|
params[:contact][:relation_ids].delete("0")
|
26
26
|
|
27
|
+
params[:contact][:user_author] = current_user
|
28
|
+
|
27
29
|
if @contact.update_attributes(params[:contact])
|
28
30
|
redirect_to @contact.receiver_subject
|
29
31
|
else
|
@@ -4,12 +4,12 @@ class ConversationsController < ApplicationController
|
|
4
4
|
before_filter :get_mailbox, :get_box, :get_actor
|
5
5
|
before_filter :check_current_subject_in_conversation, :only => [:show, :update, :destroy]
|
6
6
|
def index
|
7
|
-
if @box.eql?"inbox"
|
8
|
-
@conversations =
|
9
|
-
elsif @box.eql?"sentbox"
|
10
|
-
@conversations =
|
7
|
+
if @box.eql? "inbox"
|
8
|
+
@conversations = @mailbox.inbox.page(params[:page]).per(9)
|
9
|
+
elsif @box.eql? "sentbox"
|
10
|
+
@conversations = @mailbox.sentbox.page(params[:page]).per(9)
|
11
11
|
else
|
12
|
-
@conversations =
|
12
|
+
@conversations = @mailbox.trash.page(params[:page]).per(9)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
data/app/models/activity.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
# Activities follow the {Activity Streams}[http://activitystrea.ms/] standard.
|
2
2
|
#
|
3
|
-
# == Activities,
|
4
|
-
# Every activity is attached to a {
|
3
|
+
# == {Activity Activities}, {Channel Channels} and Audiences
|
4
|
+
# Every activity is attached to a {Channel}, which defines the sender and the receiver of the {Activity}
|
5
5
|
#
|
6
|
-
# Besides, the activity is attached to one or more relations, which define the
|
7
|
-
# the {actors Actor} that can reach it and their {permissions Permission}
|
6
|
+
# Besides, the activity is attached to one or more relations, which define the audience of the activity,
|
7
|
+
# in other words, the {actors Actor} that can reach it and their {permissions Permission}
|
8
8
|
#
|
9
9
|
# == Wall
|
10
10
|
# The Activity.wall(args) scope provides all the activities appearing in a wall
|
@@ -12,16 +12,15 @@
|
|
12
12
|
# There are two types of wall, :home and :profile. Check {Actor#wall} for more information
|
13
13
|
#
|
14
14
|
class Activity < ActiveRecord::Base
|
15
|
+
# See {SocialStream::Models::Channeled}
|
16
|
+
channeled
|
17
|
+
|
15
18
|
has_ancestry
|
16
19
|
|
17
20
|
paginates_per 10
|
18
21
|
|
19
22
|
belongs_to :activity_verb
|
20
23
|
|
21
|
-
belongs_to :contact
|
22
|
-
has_one :sender, :through => :contact
|
23
|
-
has_one :receiver, :through => :contact
|
24
|
-
|
25
24
|
has_many :audiences, :dependent => :destroy
|
26
25
|
has_many :relations, :through => :audiences
|
27
26
|
|
@@ -33,7 +32,7 @@ class Activity < ActiveRecord::Base
|
|
33
32
|
scope :wall, lambda { |args|
|
34
33
|
q =
|
35
34
|
select("DISTINCT activities.*").
|
36
|
-
joins(:
|
35
|
+
joins(:channel).
|
37
36
|
joins(:audiences).
|
38
37
|
joins(:relations).
|
39
38
|
roots
|
@@ -43,13 +42,14 @@ class Activity < ActiveRecord::Base
|
|
43
42
|
where('activity_objects.object_type' => args[:object_type])
|
44
43
|
end
|
45
44
|
|
46
|
-
|
45
|
+
channels = Channel.arel_table
|
47
46
|
audiences = Audience.arel_table
|
48
47
|
relations = Relation.arel_table
|
49
48
|
|
50
49
|
owner_conditions =
|
51
|
-
|
52
|
-
or(
|
50
|
+
channels[:author_id].eq(Actor.normalize_id(args[:owner])).
|
51
|
+
or(channels[:user_author_id].eq(Actor.normalize_id(args[:owner]))).
|
52
|
+
or(channels[:owner_id].eq(Actor.normalize_id(args[:owner])))
|
53
53
|
|
54
54
|
audience_conditions =
|
55
55
|
audiences[:relation_id].in(args[:relation_ids]).
|
@@ -59,16 +59,16 @@ class Activity < ActiveRecord::Base
|
|
59
59
|
case args[:type]
|
60
60
|
when :home
|
61
61
|
followed_conditions =
|
62
|
-
|
63
|
-
or(
|
62
|
+
channels[:author_id].in(args[:followed]).
|
63
|
+
or(channels[:owner_id].in(args[:followed]))
|
64
64
|
|
65
65
|
owner_conditions.
|
66
66
|
or(followed_conditions.and(audience_conditions))
|
67
67
|
when :profile
|
68
68
|
if args[:for].present?
|
69
69
|
visitor_conditions =
|
70
|
-
|
71
|
-
or(
|
70
|
+
channels[:author_id].eq(Actor.normalize_id(args[:for])).
|
71
|
+
or(channels[:owner_id].eq(Actor.normalize_id(args[:for])))
|
72
72
|
|
73
73
|
owner_conditions.
|
74
74
|
and(visitor_conditions.or(audience_conditions))
|
@@ -110,7 +110,7 @@ class Activity < ActiveRecord::Base
|
|
110
110
|
# This method provides the {Actor}. Use {#sender_subject} for the {SocialStream::Models::Subject Subject}
|
111
111
|
# ({User}, {Group}, etc..)
|
112
112
|
def sender
|
113
|
-
|
113
|
+
channel.author
|
114
114
|
end
|
115
115
|
|
116
116
|
# The {SocialStream::Models::Subject Subject} author of this activity
|
@@ -118,7 +118,7 @@ class Activity < ActiveRecord::Base
|
|
118
118
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
119
119
|
# Use {#sender} for the {Actor}.
|
120
120
|
def sender_subject
|
121
|
-
|
121
|
+
channel.author_subject
|
122
122
|
end
|
123
123
|
|
124
124
|
# The wall where the activity is shown belongs to receiver
|
@@ -126,7 +126,7 @@ class Activity < ActiveRecord::Base
|
|
126
126
|
# This method provides the {Actor}. Use {#receiver_subject} for the {SocialStream::Models::Subject Subject}
|
127
127
|
# ({User}, {Group}, etc..)
|
128
128
|
def receiver
|
129
|
-
|
129
|
+
channel.owner
|
130
130
|
end
|
131
131
|
|
132
132
|
# The wall where the activity is shown belongs to the receiver
|
@@ -134,7 +134,7 @@ class Activity < ActiveRecord::Base
|
|
134
134
|
# This method provides the {SocialStream::Models::Subject Subject} ({User}, {Group}, etc...).
|
135
135
|
# Use {#receiver} for the {Actor}.
|
136
136
|
def receiver_subject
|
137
|
-
|
137
|
+
channel.owner_subject
|
138
138
|
end
|
139
139
|
|
140
140
|
# The comments about this activity
|
@@ -148,7 +148,7 @@ class Activity < ActiveRecord::Base
|
|
148
148
|
end
|
149
149
|
|
150
150
|
def liked_by(user) #:nodoc:
|
151
|
-
likes.joins(:
|
151
|
+
likes.joins(:channel).merge(Channel.subject_authored_by(user))
|
152
152
|
end
|
153
153
|
|
154
154
|
# Does user like this activity?
|
@@ -157,9 +157,12 @@ class Activity < ActiveRecord::Base
|
|
157
157
|
end
|
158
158
|
|
159
159
|
# Build a new children activity where subject like this
|
160
|
-
def new_like(subject)
|
160
|
+
def new_like(subject, user)
|
161
|
+
channel = Channel.new :author => Actor.normalize(subject),
|
162
|
+
:user_author => Actor.normalize(user),
|
163
|
+
:owner => owner
|
161
164
|
a = children.new :verb => "like",
|
162
|
-
:
|
165
|
+
:channel => channel,
|
163
166
|
:relation_ids => self.relation_ids
|
164
167
|
|
165
168
|
if direct_activity_object.present?
|
@@ -207,7 +210,7 @@ class Activity < ActiveRecord::Base
|
|
207
210
|
return true if !notificable?
|
208
211
|
#Avaible verbs: follow, like, make-friend, post, update
|
209
212
|
|
210
|
-
if ['like','follow','make-friend','post','update'].include? verb and !
|
213
|
+
if ['like','follow','make-friend','post','update'].include? verb and !channel.reflexive?
|
211
214
|
receiver.notify(notification_subject, "Youre not supposed to see this", self)
|
212
215
|
end
|
213
216
|
true
|
@@ -215,15 +218,15 @@ class Activity < ActiveRecord::Base
|
|
215
218
|
|
216
219
|
# Is subject allowed to perform action on this {Activity}?
|
217
220
|
def allow?(subject, action)
|
218
|
-
return false if
|
221
|
+
return false if channel.blank?
|
219
222
|
|
220
223
|
case action
|
221
224
|
when 'create'
|
222
|
-
return false if
|
225
|
+
return false if subject.blank? || channel.author_id != Actor.normalize_id(subject)
|
223
226
|
|
224
227
|
rels = Relation.normalize(relation_ids)
|
225
228
|
|
226
|
-
own_rels = rels.select{ |r| r.actor_id ==
|
229
|
+
own_rels = rels.select{ |r| r.actor_id == channel.author_id }
|
227
230
|
foreign_rels = rels - own_rels
|
228
231
|
|
229
232
|
# Only posting to own relations or allowed to post to foreign relations
|
@@ -239,12 +242,12 @@ class Activity < ActiveRecord::Base
|
|
239
242
|
|
240
243
|
return false if subject.blank?
|
241
244
|
|
242
|
-
return true if [
|
245
|
+
return true if [channel.author_id, channel.owner_id].include?(Actor.normalize_id(subject))
|
243
246
|
when 'update'
|
244
|
-
return true if
|
247
|
+
return true if [channel.author_id, channel.owner_id].include?(Actor.normalize_id(subject))
|
245
248
|
when 'destroy'
|
246
249
|
# We only allow destroying to sender and receiver by now
|
247
|
-
return [
|
250
|
+
return [channel.author_id, channel.owner_id].include?(Actor.normalize_id(subject))
|
248
251
|
end
|
249
252
|
|
250
253
|
Relation.
|
@@ -302,10 +305,10 @@ class Activity < ActiveRecord::Base
|
|
302
305
|
|
303
306
|
# FIXME: repeated in SocialStream::Models::Object#_relation_ids
|
304
307
|
self.relation_ids =
|
305
|
-
if
|
308
|
+
if channel.reflexive?
|
306
309
|
receiver.relation_customs.map(&:id)
|
307
310
|
else
|
308
|
-
receiver.relation_customs.allow(
|
311
|
+
receiver.relation_customs.allow(channel.author, 'create', 'activity').map(&:id)
|
309
312
|
end
|
310
313
|
end
|
311
314
|
|
@@ -340,11 +343,27 @@ class Activity < ActiveRecord::Base
|
|
340
343
|
:who => I18n.t('notification.who.'+ receiver.subject.class.to_s.underscore,
|
341
344
|
:name => receiver_name))
|
342
345
|
when 'post'
|
343
|
-
|
346
|
+
if direct_object.is_a? Comment
|
347
|
+
I18n.t('notification.post.'+ receiver.subject.class.to_s.underscore,
|
344
348
|
:sender => sender_name,
|
345
|
-
|
346
|
-
|
347
|
-
|
349
|
+
:whose => I18n.t('notification.whose.'+ receiver.subject.class.to_s.underscore,
|
350
|
+
:receiver => receiver_name),
|
351
|
+
:title => 'Re: ' + direct_object.parent_post.text.truncate(30, :separator => ' '))
|
352
|
+
elsif direct_object.is_a? Post
|
353
|
+
I18n.t('notification.post.'+ receiver.subject.class.to_s.underscore,
|
354
|
+
:sender => sender_name,
|
355
|
+
:whose => I18n.t('notification.whose.'+ receiver.subject.class.to_s.underscore,
|
356
|
+
:receiver => receiver_name),
|
357
|
+
:title => direct_object.text.truncate(30, :separator => ' '))
|
358
|
+
elsif direct_object.respond_to? :title
|
359
|
+
I18n.t('notification.post.'+ receiver.subject.class.to_s.underscore,
|
360
|
+
:sender => sender_name,
|
361
|
+
:whose => I18n.t('notification.whose.'+ receiver.subject.class.to_s.underscore,
|
362
|
+
:receiver => receiver_name),
|
363
|
+
:title => direct_object.title.truncate(30, :separator => ' '))
|
364
|
+
else
|
365
|
+
I18n.t('notification.default')
|
366
|
+
end
|
348
367
|
when 'update'
|
349
368
|
I18n.t('notification.update.'+ receiver.subject.class.to_s.underscore,
|
350
369
|
:sender => sender_name,
|
@@ -9,10 +9,9 @@
|
|
9
9
|
# Objects are added to +config/initializers/social_stream.rb+
|
10
10
|
#
|
11
11
|
class ActivityObject < ActiveRecord::Base
|
12
|
-
#
|
13
|
-
|
14
|
-
|
15
|
-
:belongs => { :dependent => nil }
|
12
|
+
# See {SocialStream::Models::Channeled}
|
13
|
+
channeled
|
14
|
+
|
16
15
|
# ActivityObject is a supertype of SocialStream.objects
|
17
16
|
supertype_of :object
|
18
17
|
|
@@ -27,8 +26,6 @@ class ActivityObject < ActiveRecord::Base
|
|
27
26
|
joins(:channel).merge(Channel.authored_by(subject))
|
28
27
|
}
|
29
28
|
|
30
|
-
before_validation :check_existing_channel
|
31
|
-
|
32
29
|
# The object of this activity object
|
33
30
|
def object
|
34
31
|
subtype_instance.is_a?(Actor) ?
|
@@ -45,21 +42,4 @@ class ActivityObject < ActiveRecord::Base
|
|
45
42
|
def acts_as_actor?
|
46
43
|
object_type == "Actor"
|
47
44
|
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
|
51
|
-
def check_existing_channel
|
52
|
-
return unless channel!.new_record?
|
53
|
-
|
54
|
-
existing_channel =
|
55
|
-
Channel.
|
56
|
-
where(:author_id => author_id,
|
57
|
-
:owner_id => owner_id,
|
58
|
-
:user_author_id => user_author_id).
|
59
|
-
first
|
60
|
-
|
61
|
-
return if existing_channel.blank?
|
62
|
-
|
63
|
-
self.channel = existing_channel
|
64
|
-
end
|
65
45
|
end
|