Commit f31c657e98f20ac22457d6de4feb9d000e00aeab

Authored by Daniela Feitosa
1 parent 0d1b2d3f

AI1826

app/controllers/public/profile_controller.rb
@@ -14,6 +14,7 @@ class ProfileController < PublicController @@ -14,6 +14,7 @@ class ProfileController < PublicController
14 if logged_in? && current_person.follows?(@profile) 14 if logged_in? && current_person.follows?(@profile)
15 @network_activities = @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) if @network_activities.empty? 15 @network_activities = @profile.tracked_notifications.paginate(:per_page => 30, :page => params[:page]) if @network_activities.empty?
16 @wall_items = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) 16 @wall_items = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page])
  17 + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page])
17 end 18 end
18 @tags = profile.article_tags 19 @tags = profile.article_tags
19 unless profile.display_info_to?(user) 20 unless profile.display_info_to?(user)
@@ -180,18 +181,29 @@ class ProfileController < PublicController @@ -180,18 +181,29 @@ class ProfileController < PublicController
180 @scrap.receiver= receiver 181 @scrap.receiver= receiver
181 @tab_action = params[:tab_action] 182 @tab_action = params[:tab_action]
182 @message = @scrap.save ? _("Message successfully sent.") : _("You can't leave an empty message.") 183 @message = @scrap.save ? _("Message successfully sent.") : _("You can't leave an empty message.")
183 - @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil? 184 + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil?
184 render :partial => 'leave_scrap' 185 render :partial => 'leave_scrap'
185 end 186 end
186 187
  188 + def leave_comment_on_activity
  189 + @comment = Comment.new(params[:comment])
  190 + @comment.author = user #'if logged_in?
  191 + @comment.source = ActionTracker::Record.find(params[:comment][:source_id])
  192 + @tab_action = params[:tab_action]
  193 + @message = @comment.save ? _("Comment successfully added.") : _("You can't leave an empty comment.")
  194 + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page]) if params[:not_load_scraps].nil?
  195 + render :partial => 'leave_comment_on_activity'
  196 + end
  197 +
187 def view_more_scraps 198 def view_more_scraps
188 @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page]) 199 @scraps = @profile.scraps_received.not_replies.paginate(:per_page => 30, :page => params[:page])
189 render :partial => 'profile_scraps', :locals => {:scraps => @scraps} 200 render :partial => 'profile_scraps', :locals => {:scraps => @scraps}
190 end 201 end
191 202
192 def view_more_activities 203 def view_more_activities
193 - @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page])  
194 - render :partial => 'profile_activities', :locals => {:activities => @activities} 204 +# @activities = @profile.tracked_actions.paginate(:per_page => 30, :page => params[:page])
  205 + @activities = @profile.activities.paginate(:per_page => 30, :page => params[:page])
  206 + render :partial => 'profile_activities_scraps', :locals => {:activities => @activities}
195 end 207 end
196 208
197 def view_more_network_activities 209 def view_more_network_activities
app/models/action_tracker_notification.rb
@@ -3,9 +3,12 @@ class ActionTrackerNotification < ActiveRecord::Base @@ -3,9 +3,12 @@ class ActionTrackerNotification < ActiveRecord::Base
3 belongs_to :profile 3 belongs_to :profile
4 belongs_to :action_tracker, :class_name => 'ActionTracker::Record', :foreign_key => 'action_tracker_id' 4 belongs_to :action_tracker, :class_name => 'ActionTracker::Record', :foreign_key => 'action_tracker_id'
5 5
  6 + has_many :comments, :through => :action_tracker, :class_name => 'Comment', :foreign_key => 'source_id'
  7 +
6 validates_presence_of :profile_id, :action_tracker_id 8 validates_presence_of :profile_id, :action_tracker_id
7 validates_uniqueness_of :action_tracker_id, :scope => :profile_id 9 validates_uniqueness_of :action_tracker_id, :scope => :profile_id
8 10
9 end 11 end
10 12
11 ActionTracker::Record.has_many :action_tracker_notifications, :class_name => 'ActionTrackerNotification', :foreign_key => 'action_tracker_id', :dependent => :destroy 13 ActionTracker::Record.has_many :action_tracker_notifications, :class_name => 'ActionTrackerNotification', :foreign_key => 'action_tracker_id', :dependent => :destroy
  14 +ActionTracker::Record.has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc'
app/models/article.rb
@@ -2,9 +2,7 @@ require 'hpricot' @@ -2,9 +2,7 @@ require 'hpricot'
2 2
3 class Article < ActiveRecord::Base 3 class Article < ActiveRecord::Base
4 4
5 - track_actions :create_article, :after_create, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target  
6 - track_actions :update_article, :before_update, :keep_params => [:name, :url], :if => Proc.new { |a| a.is_trackable? && (a.body_changed? || a.name_changed?) }, :custom_target => :action_tracker_target  
7 - track_actions :remove_article, :before_destroy, :keep_params => [:name], :if => Proc.new { |a| a.is_trackable? }, :custom_target => :action_tracker_target 5 + track_actions :create_article, :after_create, :keep_params => [:name, :url, :lead], :if => Proc.new { |a| a.is_trackable? && !a.image? }, :custom_target => :action_tracker_target
8 6
9 # xss_terminate plugin can't sanitize array fields 7 # xss_terminate plugin can't sanitize array fields
10 before_save :sanitize_tag_list 8 before_save :sanitize_tag_list
@@ -17,7 +15,7 @@ class Article &lt; ActiveRecord::Base @@ -17,7 +15,7 @@ class Article &lt; ActiveRecord::Base
17 15
18 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id' 16 belongs_to :last_changed_by, :class_name => 'Person', :foreign_key => 'last_changed_by_id'
19 17
20 - has_many :comments, :dependent => :destroy, :order => 'created_at asc' 18 + has_many :comments, :dependent => :destroy, :order => 'created_at asc', :as => :source
21 19
22 has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ] 20 has_many :article_categorizations, :conditions => [ 'articles_categories.virtual = ?', false ]
23 has_many :categories, :through => :article_categorizations 21 has_many :categories, :through => :article_categorizations
@@ -134,7 +132,11 @@ class Article &lt; ActiveRecord::Base @@ -134,7 +132,11 @@ class Article &lt; ActiveRecord::Base
134 before_update do |article| 132 before_update do |article|
135 article.advertise = true 133 article.advertise = true
136 end 134 end
137 - 135 +
  136 + after_update do |article|
  137 + #update article's activity
  138 + end
  139 +
138 # retrieves all articles belonging to the given +profile+ that are not 140 # retrieves all articles belonging to the given +profile+ that are not
139 # sub-articles of any other article. 141 # sub-articles of any other article.
140 named_scope :top_level_for, lambda { |profile| 142 named_scope :top_level_for, lambda { |profile|
app/models/comment.rb
1 class Comment < ActiveRecord::Base 1 class Comment < ActiveRecord::Base
2 2
3 - track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target 3 +# track_actions :leave_comment, :after_create, :keep_params => ["article.title", "article.url", "title", "url", "body"], :custom_target => :action_tracker_target
4 4
5 validates_presence_of :body 5 validates_presence_of :body
6 - belongs_to :article, :counter_cache => true 6 +
  7 + belongs_to :source, :foreign_key => :source_id, :counter_cache => true, :polymorphic => true
  8 + alias :article :source
  9 + alias :article= :source=
  10 +
7 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id' 11 belongs_to :author, :class_name => 'Person', :foreign_key => 'author_id'
8 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy 12 has_many :children, :class_name => 'Comment', :foreign_key => 'reply_of_id', :dependent => :destroy
9 belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id' 13 belongs_to :reply_of, :class_name => 'Comment', :foreign_key => 'reply_of_id'
@@ -70,11 +74,11 @@ class Comment &lt; ActiveRecord::Base @@ -70,11 +74,11 @@ class Comment &lt; ActiveRecord::Base
70 after_save :notify_article 74 after_save :notify_article
71 after_destroy :notify_article 75 after_destroy :notify_article
72 def notify_article 76 def notify_article
73 - article.comments_updated 77 + article.comments_updated if article.kind_of?(Article)
74 end 78 end
75 79
76 after_create do |comment| 80 after_create do |comment|
77 - if comment.article.notify_comments? && !comment.article.profile.notification_emails.empty? 81 + if comment.source.kind_of?(Article) && comment.article.notify_comments? && !comment.article.profile.notification_emails.empty?
78 Comment::Notifier.deliver_mail(comment) 82 Comment::Notifier.deliver_mail(comment)
79 end 83 end
80 end 84 end
app/models/person.rb
@@ -421,6 +421,10 @@ class Person &lt; Profile @@ -421,6 +421,10 @@ class Person &lt; Profile
421 user.save! 421 user.save!
422 end 422 end
423 423
  424 + def activities
  425 + Scrap.find_by_sql("SELECT id, updated_at, '#{Scrap.to_s}' AS klass FROM #{Scrap.table_name} WHERE scraps.receiver_id = #{self.id} AND scraps.scrap_id IS NULL UNION SELECT id, updated_at, '#{ActionTracker::Record.to_s}' AS klass FROM #{ActionTracker::Record.table_name} WHERE action_tracker.user_id = #{self.id} ORDER BY updated_at DESC")
  426 + end
  427 +
424 protected 428 protected
425 429
426 def followed_by?(profile) 430 def followed_by?(profile)
app/models/profile.rb
@@ -822,6 +822,10 @@ private :generate_url, :url_options @@ -822,6 +822,10 @@ private :generate_url, :url_options
822 name 822 name
823 end 823 end
824 824
  825 + # Override in your subclasses
  826 + def activities
  827 + []
  828 + end
825 protected 829 protected
826 830
827 def followed_by?(person) 831 def followed_by?(person)
app/models/scrap.rb
@@ -11,8 +11,9 @@ class Scrap &lt; ActiveRecord::Base @@ -11,8 +11,9 @@ class Scrap &lt; ActiveRecord::Base
11 11
12 named_scope :not_replies, :conditions => {:scrap_id => nil} 12 named_scope :not_replies, :conditions => {:scrap_id => nil}
13 13
14 - track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.receiver != s.sender}, :custom_target => :action_tracker_target  
15 - track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.receiver == s.sender} 14 +######### COMO OS AMIGOS VÃO SABER Q O AMIGO RECEBEU COMENTÁRIO? ACHO QUE TEM QUE TER AÇÃO
  15 +# track_actions :leave_scrap, :after_create, :keep_params => ['sender.name', 'content', 'receiver.name', 'receiver.url'], :if => Proc.new{|s| s.receiver != s.sender}, :custom_target => :action_tracker_target
  16 +# track_actions :leave_scrap_to_self, :after_create, :keep_params => ['sender.name', 'content'], :if => Proc.new{|s| s.receiver == s.sender}
16 17
17 after_create do |scrap| 18 after_create do |scrap|
18 scrap.root.update_attribute('updated_at', DateTime.now) unless scrap.root.nil? 19 scrap.root.update_attribute('updated_at', DateTime.now) unless scrap.root.nil?
app/views/profile/_add_member_in_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => {:activity => activity} %>
app/views/profile/_comment.rhtml 0 → 100644
@@ -0,0 +1,61 @@ @@ -0,0 +1,61 @@
  1 +<li class="article-comment" style='border-bottom:none;'>
  2 + <div class="article-comment-inner">
  3 +
  4 + <div class="comment-content comment-logged-in">
  5 +
  6 + <%# if comment.author %>
  7 + <%= link_to image_tag(profile_icon(comment.author, :minor)) +
  8 + content_tag('span', comment.author_name, :class => 'comment-info'),
  9 + comment.author.url,
  10 + :class => 'comment-picture',
  11 + :title => comment.author_name
  12 + %>
  13 + <%# end %>
  14 +
  15 + <div class="comment-details">
  16 + <h4><%= comment.title %></h4>
  17 + <div class="comment-text">
  18 + <p/>
  19 + <%= txt2html comment.body %>
  20 + </div>
  21 + <div class="profile-activity-time">
  22 + <%= show_time(comment.created_at) %>
  23 + </div>
  24 + </div>
  25 +
  26 + <%# if logged_in? && (user == profile || user == comment.author || user.has_permission?(:moderate_comments, profile)) %>
  27 + <% button_bar(:style => 'float: right; margin-top: 0px;') do %>
  28 + <%= icon_button(:delete, _('Remove this comment and all its replies'), { :profile => params[:profile], :remove_comment => comment.id, :view => params[:view] }, :method => :post, :confirm => _('Are you sure you want to remove this comment and all its replies?')) %>
  29 + <% end %>
  30 + <%# end %>
  31 +
  32 + <div class="comment_reply post_comment_box closed">
  33 + <% if @comment && @comment.errors.any? && @comment.reply_of_id.to_i == comment.id %>
  34 + <%= error_messages_for :comment %>
  35 + <script type="text/javascript">
  36 + jQuery(function() {
  37 + document.location.href = '#<%= comment.anchor %>';
  38 + add_comment_reply_form('#comment-reply-to-<%= comment.id %>', <%= comment.id %>);
  39 + });
  40 + </script>
  41 + <% end %>
  42 + <%= report_abuse(comment.author, :comment_link, comment) if comment.author %>
  43 + <%= link_to_function _('Reply'),
  44 + "var f = add_comment_reply_form(this, %s); f.find('input[name=comment[title]], textarea').val(''); return false" % comment.id,
  45 + :class => 'comment-footer comment-footer-link comment-footer-hide',
  46 + :id => 'comment-reply-to-' + comment.id.to_s
  47 + %>
  48 + </div>
  49 +
  50 + </div>
  51 +
  52 + <% unless comment.replies.blank? %>
  53 + <ul class="comment-replies">
  54 + <% comment.replies.each do |reply| %>
  55 + <%= render :partial => 'comment', :locals => { :comment => reply } %>
  56 + <% end %>
  57 + </ul>
  58 + <% end %>
  59 +
  60 + </div>
  61 +</li>
app/views/profile/_create_article.rhtml 0 → 100644
@@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
  1 +<div class='profile-activity-image'>
  2 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  3 +</div>
  4 +<div class='profile-activity-description'>
  5 + <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
  6 + <p class='profile-activity-text'><%= activity.params['lead'] %></p>
  7 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p>
  8 + <div class='profile-wall-actions'>
  9 + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  10 + </div>
  11 +</div>
app/views/profile/_default_activity.rhtml 0 → 100644
@@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
  1 +<div class='profile-activity-image'>
  2 + <%= link_to(profile_image(activity.user, :minor), activity.user.url) %>
  3 +</div>
  4 +<div class='profile-activity-description'>
  5 + <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>
  6 + <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p>
  7 + <div class='profile-wall-actions'>
  8 + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if logged_in? && current_person == @profile %>
  9 + </div>
  10 +</div>
app/views/profile/_join_community.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => {:activity => activity} %>
app/views/profile/_leave_comment_on_activity.rhtml 0 → 100644
@@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
  1 +<%= @message %>
  2 +<% unless @activities.nil? %>
  3 + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %>
  4 +<% end %>
app/views/profile/_leave_scrap.rhtml
1 <%= @message %> 1 <%= @message %>
2 -<% unless @scraps.nil? %>  
3 - <%= render :partial => 'profile_scraps', :locals => {:scraps => @scraps} %> 2 +<% unless @activities.nil? %>
  3 + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %>
4 <% end %> 4 <% end %>
app/views/profile/_new_friendship.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => {:activity => activity} %>
app/views/profile/_profile_activities.rhtml
1 -<% activities.each do |activity| %>  
2 - <li class='profile-activity-item <%= activity.verb %>' id='profile-activity-item-<%= activity.id %>'>  
3 - <div class='profile-activity-image'>  
4 - <%= link_to(profile_image(activity.user, :minor), activity.user.url) %> 1 +<li class='profile-activity-item <%= activity.verb %>' id='profile-activity-item-<%= activity.id %>'>
  2 + <%= render :partial => activity.verb, :locals => { :activity => activity }%>
  3 + <hr />
  4 +
  5 + <%# if logged_in? && current_person.follows?(activity.sender) && activity.root.nil? %>
  6 + <span class='profile-wall-send-reply'><%= link_to_function _('Comment'), "hide_and_show(['#profile-wall-reply-response-#{activity.id}'],['#profile-wall-reply-#{activity.id}', '#profile-wall-reply-form-#{activity.id}']);$('reply_content_#{activity.id}').value='';$('activity_id_#{activity.id}').value='#{activity.id}';return false", :class => "profile-send-reply" %></span>
  7 + <%# end %>
  8 +
  9 + <ul class="profile-wall-activities-comments" style='padding-left: 50px;width:auto'>
  10 + <%= render :partial => 'comment', :collection => activity.comments %>
  11 + </ul>
  12 +
  13 + <div id='profile-wall-reply-<%= activity.id%>' style='display:none;width:auto;'>
  14 + <div id='profile-wall-reply-form-<%= activity.id%>' style='display:none;'>
  15 + <p class='profile-wall-reply'>
  16 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_comment_on_activity'}, :update => "profile_activities", :success =>"hide_and_show(['#profile-wall-reply-form-#{activity.id}'],['#profile-wall-reply-response-#{activity.id}'])" do %>
  17 + <%= limited_text_area :comment, :body, 420, "reply_content_#{activity.id}", :cols => 50, :rows => 2 %>
  18 + <%= hidden_field :comment, :source_id, :id => "activity_id_#{activity.id}" %>
  19 + <%= hidden_field :comment, :author_id, :value => user.id %>
  20 + <%= submit_button :add, _('Leave a comment') %>
  21 + <%= button_to_function :cancel, _('Cancel'), "hide_and_show(['#profile-wall-reply-#{activity.id}'],[]);return false" %>
  22 + <% end %>
  23 + </p>
5 </div> 24 </div>
6 - <div class='profile-activity-description'>  
7 - <p class='profile-activity-time'><%= time_ago_as_sentence(activity.created_at) + ' ' + _('ago') %></p>  
8 - <p class='profile-activity-text'><%= link_to activity.user.name, activity.user.url %> <%= describe activity %></p>  
9 - <%= button_to_remote(:delete, content_tag(:span, _('Remove')), :url =>{:action => 'remove_activity', :activity_id => activity.id}, :update => "profile-activity-item-#{activity.id}") if can_edit_profile %>  
10 - </div>  
11 - <hr />  
12 - </li>  
13 -<% end %>  
14 -<% if activities.current_page < activities.total_pages %>  
15 - <div id='profile_activities_page_<%= activities.current_page %>'>  
16 - <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_activities', :page => (activities.current_page + 1)}, :update => "profile_activities_page_#{activities.current_page}" %> 25 + <div id='profile-wall-message-response-<%=activity.id%>' class='profile-wall-message-response'></div>
17 </div> 26 </div>
18 -<% end %> 27 +
  28 +</li>
app/views/profile/_profile_activities_scraps.rhtml 0 → 100644
@@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
  1 +<% activities.each do |a| %>
  2 + <% activity = a.klass.constantize.find(a.id) %>
  3 + <% if activity.kind_of?(ActionTracker::Record) && @profile.person? %>
  4 + <%= render :partial => 'profile_activities', :locals => {:activity => activity} %>
  5 + <% else %>
  6 + <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %>
  7 + <% end %>
  8 +<% end %>
app/views/profile/_profile_activity.rhtml
1 <div id='profile-activity'> 1 <div id='profile-activity'>
2 <h3><%= _("%s's activity") % @profile.name %></h3> 2 <h3><%= _("%s's activity") % @profile.name %></h3>
3 <ul> 3 <ul>
4 - <%= render :partial => 'profile_activities', :locals => {:activities => @activities} %> 4 + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %>
5 </ul> 5 </ul>
6 </div> 6 </div>
app/views/profile/_profile_scrap.rhtml
@@ -7,13 +7,15 @@ @@ -7,13 +7,15 @@
7 </div> 7 </div>
8 <% comment_balloon :class => 'profile-wall-description' do %> 8 <% comment_balloon :class => 'profile-wall-description' do %>
9 <p class='profile-wall-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p> 9 <p class='profile-wall-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
10 - <p class='profile-wall-time'><%= time_ago_as_sentence(scrap.created_at) + ' ' + _('ago') %></p>  
11 <p class='profile-wall-text'><%= txt2html scrap.content %></p> 10 <p class='profile-wall-text'><%= txt2html scrap.content %></p>
12 - <%= button_to_remote(:delete, content_tag(:span, _('Remove')), :url =>{:action => 'remove_scrap', :scrap_id => scrap.id}, :update => "profile-wall-item-#{scrap.id}") if logged_in? && user.can_control_scrap?(scrap) %> 11 + <p class='profile-wall-time'><%= time_ago_as_sentence(scrap.created_at) + ' ' + _('ago') %></p>
  12 + <div class='profile-wall-actions'>
13 <% if logged_in? && current_person.follows?(scrap.sender) && scrap.root.nil? %> 13 <% if logged_in? && current_person.follows?(scrap.sender) && scrap.root.nil? %>
14 - <p class='profile-wall-send-reply'><%= link_to_function _('Reply'), "hide_and_show(['#profile-wall-reply-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('scrap_id_#{scrap.id}').value='#{scrap.id}';return false", :class => "profile-send-reply icon-reply" %></p> 14 + <span class='profile-wall-send-reply'><%= link_to_function _('Comment'), "hide_and_show(['#profile-wall-reply-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('scrap_id_#{scrap.id}').value='#{scrap.id}';return false", :class => "profile-send-reply" %></span>
15 <% end %> 15 <% end %>
  16 + <%= link_to_remote(content_tag(:span, _('Remove')), :url =>{:action => 'remove_scrap', :scrap_id => scrap.id}, :update => "profile-wall-item-#{scrap.id}") if logged_in? && user.can_control_scrap?(scrap) %>
16 <% end %> 17 <% end %>
  18 + </div>
17 <ul class="profile-wall-scrap-replies"> 19 <ul class="profile-wall-scrap-replies">
18 <% scrap.replies.map do |reply| %> 20 <% scrap.replies.map do |reply| %>
19 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> 21 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %>
@@ -35,7 +37,7 @@ @@ -35,7 +37,7 @@
35 <div id='profile-wall-reply-<%= scrap.id%>' style='display:none;'> 37 <div id='profile-wall-reply-<%= scrap.id%>' style='display:none;'>
36 <div id='profile-wall-reply-form-<%= scrap.id%>' style='display:none;'> 38 <div id='profile-wall-reply-form-<%= scrap.id%>' style='display:none;'>
37 <p class='profile-wall-reply'> 39 <p class='profile-wall-reply'>
38 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap'}, :update => "profile_scraps", :success =>"hide_and_show(['#profile-wall-reply-form-#{scrap.id}'],['#profile-wall-reply-response-#{scrap.id}'])" do %> 40 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap'}, :update => "profile_activities", :success =>"hide_and_show(['#profile-wall-reply-form-#{scrap.id}'],['#profile-wall-reply-response-#{scrap.id}'])" do %>
39 <%= limited_text_area :scrap, :content, 420, "reply_content_#{scrap.id}", :cols => 50, :rows => 2 %> 41 <%= limited_text_area :scrap, :content, 420, "reply_content_#{scrap.id}", :cols => 50, :rows => 2 %>
40 <%= hidden_field :scrap, :scrap_id, :id => "scrap_id_#{scrap.id}" %> 42 <%= hidden_field :scrap, :scrap_id, :id => "scrap_id_#{scrap.id}" %>
41 <%= hidden_field_tag 'receiver_id', scrap.sender.id %> 43 <%= hidden_field_tag 'receiver_id', scrap.sender.id %>
app/views/profile/_profile_wall.rhtml
1 <h3><%= _("%s's wall") % @profile.name %></h3> 1 <h3><%= _("%s's wall") % @profile.name %></h3>
2 <div id='leave_scrap'> 2 <div id='leave_scrap'>
3 <%= flash[:error] %> 3 <%= flash[:error] %>
4 - <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_scraps', :success => "$('leave_scrap_content').value=''" do %> 4 + <% form_remote_tag :url => {:controller => 'profile', :action => 'leave_scrap', :tab_action => 'wall' }, :update => 'profile_activities', :success => "$('leave_scrap_content').value=''" do %>
5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %> 5 <%= limited_text_area :scrap, :content, 420, 'leave_scrap_content', :cols => 50, :rows => 2 %>
6 <%= submit_button :scrap, _('Leave a scrap') %> 6 <%= submit_button :scrap, _('Leave a scrap') %>
7 <% end %> 7 <% end %>
8 </div> 8 </div>
9 <div id='leave_scrap_response'></div> 9 <div id='leave_scrap_response'></div>
  10 +<ul id='profile_activities'>
  11 + <%= render :partial => 'profile_activities_scraps', :locals => {:activities => @activities} %>
  12 +</ul>
  13 +
  14 +<% if @activities.current_page < @activities.total_pages %>
  15 + <div id='profile_activities_page_<%= @activities.current_page %>'>
  16 + <%= button_to_remote :add, _('View more'), :url => {:action => 'view_more_activities', :page => (@activities.current_page + 1)}, :update => "profile_activities_page_#{@activities.current_page}" %>
  17 + </div>
  18 +<% end %>
  19 +
  20 +<!--
10 <ul id='profile_scraps'> 21 <ul id='profile_scraps'>
11 - <%= render :partial => 'profile_scraps', :locals => {:scraps => @wall_items} %> 22 + <%#= render :partial => 'profile_scraps', :locals => {:scraps => @wall_items} %>
12 </ul> 23 </ul>
  24 +
  25 +<% if @profile.person? %>
  26 + <%#= render :partial => 'profile_activity' %>
  27 +<% end %>
  28 +-->
app/views/profile/_update_article.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => {:activity => activity} %>
app/views/profile/_upload_image.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +<%= render :partial => 'default_activity', :locals => {:activity => activity} %>
config/initializers/action_tracker.rb
@@ -5,13 +5,7 @@ require &#39;noosfero/i18n&#39; @@ -5,13 +5,7 @@ require &#39;noosfero/i18n&#39;
5 ActionTrackerConfig.verbs = { 5 ActionTrackerConfig.verbs = {
6 6
7 :create_article => { 7 :create_article => {
8 - :description => lambda { n_('published 1 article: %{title}', 'published %{num} articles: %{title}', get_name.size) % { :num => get_name.size, :title => '{{ta.collect_group_with_index(:name){ |n,i| link_to(truncate(n), ta.get_url[i]) }.to_sentence(:connector => "%s")}}' % _("and") } },  
9 - :type => :groupable  
10 - },  
11 -  
12 - :update_article => {  
13 - :description => lambda { n_('updated 1 article: %{title}', 'updated %{num} articles: %{title}', get_name.uniq.size) % { :num => get_name.uniq.size, :title => '{{ta.collect_group_with_index(:name){ |n,i| link_to(truncate(n), ta.get_url[i]) }.uniq.to_sentence(:connector => "%s")}}' % _("and") } },  
14 - :type => :groupable 8 + :description => lambda { _('published an article: %{title}') % { :title => '{{link_to(truncate(ta.get_name), ta.get_url)}}' } }
15 }, 9 },
16 10
17 :remove_article => { 11 :remove_article => {
db/migrate/20111211204445_add_polymorphism_on_comment.rb 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +class AddPolymorphismOnComment < ActiveRecord::Migration
  2 + def self.up
  3 + rename_column :comments, :article_id, :source_id
  4 + add_column :comments, :source_type, :string
  5 + execute("update comments set source_type = 'Article'")
  6 + end
  7 +
  8 + def self.down
  9 + remove_column :comments, :source_type
  10 + rename_column :comments, :source_id, :article_id
  11 + end
  12 +end
db/migrate/20111211233957_add_comment_count_to_action_tracker.rb 0 → 100644
@@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
  1 +class AddCommentCountToActionTracker < ActiveRecord::Migration
  2 + def self.up
  3 + add_column :action_tracker, :comments_count, :integer, :default => 0
  4 + end
  5 +
  6 + def self.down
  7 + remove_column :action_tracker, :comments_count, :integer, :default => 0
  8 + end
  9 +end
@@ -29,6 +29,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -29,6 +29,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
29 t.string "verb" 29 t.string "verb"
30 t.datetime "created_at" 30 t.datetime "created_at"
31 t.datetime "updated_at" 31 t.datetime "updated_at"
  32 + t.integer "comments_count", :default => 0
32 end 33 end
33 34
34 add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type" 35 add_index "action_tracker", ["target_id", "target_type"], :name => "index_action_tracker_on_dispatcher_id_and_dispatcher_type"
@@ -198,7 +199,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -198,7 +199,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
198 create_table "comments", :force => true do |t| 199 create_table "comments", :force => true do |t|
199 t.string "title" 200 t.string "title"
200 t.text "body" 201 t.text "body"
201 - t.integer "article_id" 202 + t.integer "source_id"
202 t.integer "author_id" 203 t.integer "author_id"
203 t.string "name" 204 t.string "name"
204 t.string "email" 205 t.string "email"
@@ -206,6 +207,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -206,6 +207,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
206 t.integer "reply_of_id" 207 t.integer "reply_of_id"
207 t.string "ip_address" 208 t.string "ip_address"
208 t.boolean "spam" 209 t.boolean "spam"
  210 + t.string "source_type"
209 end 211 end
210 212
211 create_table "contact_lists", :force => true do |t| 213 create_table "contact_lists", :force => true do |t|
@@ -252,6 +254,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -252,6 +254,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
252 t.datetime "created_at" 254 t.datetime "created_at"
253 t.datetime "updated_at" 255 t.datetime "updated_at"
254 t.integer "reports_lower_bound", :default => 0, :null => false 256 t.integer "reports_lower_bound", :default => 0, :null => false
  257 + t.text "send_email_plugin_allow_to"
255 end 258 end
256 259
257 create_table "external_feeds", :force => true do |t| 260 create_table "external_feeds", :force => true do |t|
@@ -384,7 +387,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -384,7 +387,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
384 t.string "type" 387 t.string "type"
385 t.string "identifier" 388 t.string "identifier"
386 t.integer "environment_id" 389 t.integer "environment_id"
387 - t.boolean "active", :default => true 390 + t.boolean "active", :default => true
388 t.string "address" 391 t.string "address"
389 t.string "contact_phone" 392 t.string "contact_phone"
390 t.integer "home_page_id" 393 t.integer "home_page_id"
@@ -395,19 +398,24 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -395,19 +398,24 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
395 t.float "lat" 398 t.float "lat"
396 t.float "lng" 399 t.float "lng"
397 t.integer "geocode_precision" 400 t.integer "geocode_precision"
398 - t.boolean "enabled", :default => true  
399 - t.string "nickname", :limit => 16 401 + t.boolean "enabled", :default => true
  402 + t.string "nickname", :limit => 16
400 t.text "custom_header" 403 t.text "custom_header"
401 t.text "custom_footer" 404 t.text "custom_footer"
402 t.string "theme" 405 t.string "theme"
403 - t.boolean "public_profile", :default => true 406 + t.boolean "public_profile", :default => true
404 t.date "birth_date" 407 t.date "birth_date"
405 t.integer "preferred_domain_id" 408 t.integer "preferred_domain_id"
406 t.datetime "updated_at" 409 t.datetime "updated_at"
407 - t.boolean "visible", :default => true 410 + t.boolean "visible", :default => true
408 t.integer "image_id" 411 t.integer "image_id"
409 - t.boolean "validated", :default => true 412 + t.boolean "validated", :default => true
410 t.string "cnpj" 413 t.string "cnpj"
  414 + t.boolean "shopping_cart", :default => true
  415 + t.boolean "shopping_cart_delivery", :default => false
  416 + t.decimal "shopping_cart_delivery_price", :default => 0.0
  417 + t.integer "bsc_id"
  418 + t.string "company_name"
411 end 419 end
412 420
413 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id" 421 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
@@ -496,6 +504,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do @@ -496,6 +504,7 @@ ActiveRecord::Schema.define(:version =&gt; 20120307200651) do
496 t.datetime "created_at" 504 t.datetime "created_at"
497 t.string "target_type" 505 t.string "target_type"
498 t.integer "image_id" 506 t.integer "image_id"
  507 + t.integer "bsc_id"
499 end 508 end
500 509
501 create_table "thumbnails", :force => true do |t| 510 create_table "thumbnails", :force => true do |t|
public/designs/themes/base/style.css
@@ -1053,53 +1053,53 @@ hr.pre-posts, hr.sep-posts { @@ -1053,53 +1053,53 @@ hr.pre-posts, hr.sep-posts {
1053 1053
1054 .comment-wrapper-1 { 1054 .comment-wrapper-1 {
1055 margin-left: 60px; 1055 margin-left: 60px;
1056 - background: url(imgs/comment-bg-N.png) 0% 0% repeat-x; 1056 + Xbackground: url(imgs/comment-bg-N.png) 0% 0% repeat-x;
1057 } 1057 }
1058 .comment-wrapper-2 { 1058 .comment-wrapper-2 {
1059 - background: url(imgs/comment-bg-S.png) 0% 100% repeat-x; 1059 + Xbackground: url(imgs/comment-bg-S.png) 0% 100% repeat-x;
1060 } 1060 }
1061 .comment-wrapper-3 { 1061 .comment-wrapper-3 {
1062 - background: url(imgs/comment-bg-L.png) 100% 0% repeat-y; 1062 + Xbackground: url(imgs/comment-bg-L.png) 100% 0% repeat-y;
1063 } 1063 }
1064 .comment-wrapper-4 { 1064 .comment-wrapper-4 {
1065 - background: url(imgs/comment-bg-O.png) 0% 0% repeat-y; 1065 + Xbackground: url(imgs/comment-bg-O.png) 0% 0% repeat-y;
1066 } 1066 }
1067 .comment-wrapper-5 { 1067 .comment-wrapper-5 {
1068 - background: url(imgs/comment-bg-SL.png) 100% 100% no-repeat; 1068 + Xbackground: url(imgs/comment-bg-SL.png) 100% 100% no-repeat;
1069 } 1069 }
1070 .comment-wrapper-6 { 1070 .comment-wrapper-6 {
1071 - background: url(imgs/comment-bg-SO.png) 0% 100% no-repeat; 1071 + Xbackground: url(imgs/comment-bg-SO.png) 0% 100% no-repeat;
1072 } 1072 }
1073 .comment-wrapper-7 { 1073 .comment-wrapper-7 {
1074 - background: url(imgs/comment-bg-NL.png) 100% 0% no-repeat; 1074 + Xbackground: url(imgs/comment-bg-NL.png) 100% 0% no-repeat;
1075 } 1075 }
1076 .comment-wrapper-8 { 1076 .comment-wrapper-8 {
1077 - background: url(imgs/comment-bg-NO.png) 0% 0% no-repeat; 1077 + Xbackground: url(imgs/comment-bg-NO.png) 0% 0% no-repeat;
1078 } 1078 }
1079 1079
1080 .comment-from-owner .comment-wrapper-1 { 1080 .comment-from-owner .comment-wrapper-1 {
1081 - background: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x; 1081 + Xbackground: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x;
1082 } 1082 }
1083 .comment-from-owner .comment-wrapper-2 { 1083 .comment-from-owner .comment-wrapper-2 {
1084 - background: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x; 1084 + Xbackground: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x;
1085 } 1085 }
1086 .comment-from-owner .comment-wrapper-3 { 1086 .comment-from-owner .comment-wrapper-3 {
1087 - background: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y; 1087 + Xbackground: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y;
1088 } 1088 }
1089 .comment-from-owner .comment-wrapper-4 { 1089 .comment-from-owner .comment-wrapper-4 {
1090 - background: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y; 1090 + Xbackground: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y;
1091 } 1091 }
1092 .comment-from-owner .comment-wrapper-5 { 1092 .comment-from-owner .comment-wrapper-5 {
1093 - background: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat; 1093 + Xbackground: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat;
1094 } 1094 }
1095 .comment-from-owner .comment-wrapper-6 { 1095 .comment-from-owner .comment-wrapper-6 {
1096 - background: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat; 1096 + Xbackground: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat;
1097 } 1097 }
1098 .comment-from-owner .comment-wrapper-7 { 1098 .comment-from-owner .comment-wrapper-7 {
1099 - background: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat; 1099 + Xbackground: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat;
1100 } 1100 }
1101 .comment-from-owner .comment-wrapper-8 { 1101 .comment-from-owner .comment-wrapper-8 {
1102 - background: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat; 1102 + Xbackground: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat;
1103 } 1103 }
1104 1104
1105 .comment-created-at { 1105 .comment-created-at {
public/stylesheets/application.css
@@ -1314,7 +1314,7 @@ a.comment-picture { @@ -1314,7 +1314,7 @@ a.comment-picture {
1314 } 1314 }
1315 1315
1316 .comment-balloon-content { 1316 .comment-balloon-content {
1317 - margin-left: 15px; 1317 + Xmargin-left: 15px;
1318 } 1318 }
1319 1319
1320 /* * * Comment Replies * * */ 1320 /* * * Comment Replies * * */
@@ -5883,7 +5883,15 @@ h1#agenda-title { @@ -5883,7 +5883,15 @@ h1#agenda-title {
5883 #profile-activity li, #profile-network li, #profile-wall li { 5883 #profile-activity li, #profile-network li, #profile-wall li {
5884 display: block; 5884 display: block;
5885 padding: 0; 5885 padding: 0;
5886 - margin-bottom: 8px; 5886 + Xmargin-bottom: 8px;
  5887 + background-color: #E8E8E8;
  5888 + border-bottom: 5px double #f2f2f2;
  5889 +}
  5890 +
  5891 +#profile-activity .profile-wall-scrap-replies li,
  5892 +#profile-network .profile-wall-scrap-replies li,
  5893 +#profile-wall .profile-wall-scrap-replies li {
  5894 + border-bottom: none;
5887 } 5895 }
5888 5896
5889 #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image { 5897 #profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image {
@@ -5897,12 +5905,12 @@ h1#agenda-title { @@ -5897,12 +5905,12 @@ h1#agenda-title {
5897 5905
5898 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { 5906 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description {
5899 float: left; 5907 float: left;
5900 - min-height: 60px; 5908 + Xmin-height: 60px;
5901 margin: 0; 5909 margin: 0;
5902 padding: 0; 5910 padding: 0;
5903 border: 1px solid #ccc; 5911 border: 1px solid #ccc;
5904 overflow: hidden; 5912 overflow: hidden;
5905 - background-color: #fff; 5913 + Xbackground-color: #fff;
5906 position: relative; 5914 position: relative;
5907 } 5915 }
5908 5916
@@ -5931,17 +5939,18 @@ h1#agenda-title { @@ -5931,17 +5939,18 @@ h1#agenda-title {
5931 5939
5932 #profile-activity .profile-activity-text, #profile-network .profile-network-text, #profile-wall .profile-wall-text { 5940 #profile-activity .profile-activity-text, #profile-network .profile-network-text, #profile-wall .profile-wall-text {
5933 font-size: 13px; 5941 font-size: 13px;
5934 - margin: 5px; 5942 + margin: 2px 5px;
5935 } 5943 }
5936 5944
5937 #profile-wall .profile-wall-text { 5945 #profile-wall .profile-wall-text {
5938 padding-top: 0; 5946 padding-top: 0;
5939 } 5947 }
5940 5948
5941 -#profile-activity .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time { 5949 +#profile_activities .profile-activity-time, #profile-network .profile-network-time, #profile-wall .profile-wall-time {
5942 font-size: 11px; 5950 font-size: 11px;
5943 margin: 5px; 5951 margin: 5px;
5944 color: #babdb6; 5952 color: #babdb6;
  5953 + text-align: right;
5945 } 5954 }
5946 5955
5947 #profile-activity hr, #profile-network hr, #profile-wall hr { 5956 #profile-activity hr, #profile-network hr, #profile-wall hr {
@@ -6083,21 +6092,30 @@ h1#agenda-title { @@ -6083,21 +6092,30 @@ h1#agenda-title {
6083 } 6092 }
6084 6093
6085 .profile-send-reply { 6094 .profile-send-reply {
6086 - background-color: #eee;  
6087 - border: 1px solid #aaa;  
6088 - padding: 2px;  
6089 - padding-left: 20px;  
6090 - background-repeat: no-repeat;  
6091 - background-position: 2px center; 6095 + xbackground-color: #eee;
  6096 + xborder: 1px solid #aaa;
  6097 + xpadding: 2px;
  6098 + xpadding-left: 20px;
  6099 + xbackground-repeat: no-repeat;
  6100 + xbackground-position: 2px center;
6092 color: #aaa; 6101 color: #aaa;
6093 - text-decoration: none;  
6094 - margin-left: 8px; 6102 + Xtext-decoration: none;
  6103 + Xmargin-left: 8px;
6095 } 6104 }
6096 6105
6097 #content .profile-send-reply:hover { 6106 #content .profile-send-reply:hover {
6098 text-decoration: none; 6107 text-decoration: none;
6099 } 6108 }
6100 6109
  6110 +#profile-wall .profile-wall-actions {
  6111 + text-align: right;
  6112 +}
  6113 +
  6114 +#profile-wall .profile-wall-send-reply {
  6115 + display: inline-block;
  6116 +
  6117 +}
  6118 +
6101 #profile-wall .profile-wall-scrap-replies .profile-wall-description { 6119 #profile-wall .profile-wall-scrap-replies .profile-wall-description {
6102 background: transparent; 6120 background: transparent;
6103 } 6121 }
@@ -6244,7 +6262,7 @@ h1#agenda-title { @@ -6244,7 +6262,7 @@ h1#agenda-title {
6244 } 6262 }
6245 6263
6246 #profile-wall .comment-balloon-content { 6264 #profile-wall .comment-balloon-content {
6247 - padding: 3px 0 3px 15px; 6265 + padding: 3px 0px;
6248 } 6266 }
6249 6267
6250 .profile-wall-reply { 6268 .profile-wall-reply {
@@ -6266,8 +6284,9 @@ h1#agenda-title { @@ -6266,8 +6284,9 @@ h1#agenda-title {
6266 width: 98%; 6284 width: 98%;
6267 } 6285 }
6268 6286
6269 -#profile-activity .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image {  
6270 - width: 19%; 6287 +#profile_activities .profile-activity-image, #profile-network .profile-network-image, #profile-wall .profile-wall-image {
  6288 + width: 50px;
  6289 + margin: 5px;
6271 } 6290 }
6272 6291
6273 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description { 6292 #profile-activity .profile-activity-description, #profile-network .profile-network-description, #profile-wall .profile-wall-description {
test/factories.rb
@@ -438,7 +438,7 @@ module Noosfero::Factory @@ -438,7 +438,7 @@ module Noosfero::Factory
438 438
439 def defaults_for_comment(params = {}) 439 def defaults_for_comment(params = {})
440 name = "comment_#{rand(1000)}" 440 name = "comment_#{rand(1000)}"
441 - { :title => name, :body => "my own comment", :article_id => 1 }.merge(params) 441 + { :title => name, :body => "my own comment", :source_id => 1 }.merge(params)
442 end 442 end
443 443
444 ############################################### 444 ###############################################
test/functional/profile_controller_test.rb
@@ -714,21 +714,27 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -714,21 +714,27 @@ class ProfileControllerTest &lt; ActionController::TestCase
714 assert_no_tag :tag => 'p', :content => 'A scrap' 714 assert_no_tag :tag => 'p', :content => 'A scrap'
715 end 715 end
716 716
717 - should 'see all activities of the current profile' do 717 + should 'see only actions of the current profile when he is not followed by the viewer' do
718 p1= Person.first 718 p1= Person.first
719 p2= fast_create(Person) 719 p2= fast_create(Person)
720 - assert !p1.is_a_friend?(p2)  
721 p3= fast_create(Person) 720 p3= fast_create(Person)
722 - assert !p1.is_a_friend?(p3) 721 +
  722 +# UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
723 ActionTracker::Record.destroy_all 723 ActionTracker::Record.destroy_all
724 - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 724 + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
  725 +
  726 +# UserStampSweeper.any_instance.stubs(:current_user).returns(p2)
  727 + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
  728 +# a2 = ActionTracker::Record.last
  729 +
  730 +# UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
  731 + scrap3 = Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
  732 +# a3 = ActionTracker::Record.last
  733 +
  734 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
  735 + TinyMceArticle.create!(:profile => p1, :name => 'An article about free software')
725 a1 = ActionTracker::Record.last 736 a1 = ActionTracker::Record.last
726 - UserStampSweeper.any_instance.stubs(:current_user).returns(p2)  
727 - Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))  
728 - a2 = ActionTracker::Record.last  
729 - UserStampSweeper.any_instance.stubs(:current_user).returns(p3)  
730 - Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))  
731 - a3 = ActionTracker::Record.last 737 +
732 login_as(profile.identifier) 738 login_as(profile.identifier)
733 get :index, :profile => p1.identifier 739 get :index, :profile => p1.identifier
734 assert_not_nil assigns(:activities) 740 assert_not_nil assigns(:activities)
@@ -744,7 +750,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -744,7 +750,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
744 assert_equal 30, assigns(:activities).count 750 assert_equal 30, assigns(:activities).count
745 end 751 end
746 752
747 - should 'see not see the friends activities in the current profile activity' do 753 + should 'not see the friends actions and scraps in the current profile activity' do
748 p1= Person.first 754 p1= Person.first
749 p2= fast_create(Person) 755 p2= fast_create(Person)
750 assert !p1.is_a_friend?(p2) 756 assert !p1.is_a_friend?(p2)
@@ -752,18 +758,23 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -752,18 +758,23 @@ class ProfileControllerTest &lt; ActionController::TestCase
752 p1.add_friend(p3) 758 p1.add_friend(p3)
753 assert p1.is_a_friend?(p3) 759 assert p1.is_a_friend?(p3)
754 ActionTracker::Record.destroy_all 760 ActionTracker::Record.destroy_all
755 - Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1)) 761 +
  762 + scrap1 = Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))
  763 + scrap2 = Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3))
  764 + scrap3 = Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))
  765 +
  766 + UserStampSweeper.any_instance.stubs(:current_user).returns(p3)
  767 + TinyMceArticle.create!(:profile => p3, :name => 'An article about free software')
756 a1 = ActionTracker::Record.last 768 a1 = ActionTracker::Record.last
757 - UserStampSweeper.any_instance.stubs(:current_user).returns(p2)  
758 - Scrap.create!(defaults_for_scrap(:sender => p2, :receiver => p3)) 769 +
  770 + UserStampSweeper.any_instance.stubs(:current_user).returns(p1)
  771 + TinyMceArticle.create!(:profile => p1, :name => 'Another article about free software')
759 a2 = ActionTracker::Record.last 772 a2 = ActionTracker::Record.last
760 - UserStampSweeper.any_instance.stubs(:current_user).returns(p3)  
761 - Scrap.create!(defaults_for_scrap(:sender => p3, :receiver => p1))  
762 - a3 = ActionTracker::Record.last 773 +
763 login_as(profile.identifier) 774 login_as(profile.identifier)
764 get :index, :profile => p1.identifier 775 get :index, :profile => p1.identifier
765 assert_not_nil assigns(:activities) 776 assert_not_nil assigns(:activities)
766 - assert_equal [a1], assigns(:activities) 777 + assert_equal [a2], assigns(:activities)
767 end 778 end
768 779
769 should 'see all the activities in the current profile network' do 780 should 'see all the activities in the current profile network' do
@@ -976,7 +987,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -976,7 +987,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
976 987
977 should 'the wall_itens be paginated in people profiles' do 988 should 'the wall_itens be paginated in people profiles' do
978 p1 = Person.first 989 p1 = Person.first
979 - 40.times{fast_create(Scrap, :sender_id => p1.id)} 990 + 40.times{fast_create(Scrap, :sender_id => p1.id, :created_at => Time.now)}
980 991
981 @controller.stubs(:logged_in?).returns(true) 992 @controller.stubs(:logged_in?).returns(true)
982 user = mock() 993 user = mock()
@@ -1158,7 +1169,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1158,7 +1169,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
1158 assert_equal 40, profile.tracked_actions.count 1169 assert_equal 40, profile.tracked_actions.count
1159 get :view_more_activities, :profile => profile.identifier, :page => 2 1170 get :view_more_activities, :profile => profile.identifier, :page => 2
1160 assert_response :success 1171 assert_response :success
1161 - assert_template '_profile_activities' 1172 + assert_template '_profile_bla'
1162 assert_equal 10, assigns(:activities).count 1173 assert_equal 10, assigns(:activities).count
1163 end 1174 end
1164 1175
@@ -1247,4 +1258,34 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1247,4 +1258,34 @@ class ProfileControllerTest &lt; ActionController::TestCase
1247 post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'} 1258 post :register_report, :profile => reported.identifier, :abuse_report => {:reason => 'some reason'}
1248 end 1259 end
1249 end 1260 end
  1261 +
  1262 + should 'display activities and scraps together' do
  1263 + another_person = fast_create(Person)
  1264 + Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  1265 +
  1266 + UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
  1267 + ActionTracker::Record.destroy_all
  1268 + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1269 +
  1270 + login_as(profile.identifier)
  1271 + get :index, :profile => profile.identifier
  1272 +
  1273 + assert_tag :tag => 'div', :attributes => { :id => 'profile-wall' }, :descendant => { :tag => 'p', :content => 'A scrap' }
  1274 + assert_tag :tag => 'div', :attributes => { :id => 'profile-wall' }, :descendant => { :tag => 'a', :content => 'An article about free software' }
  1275 + end
  1276 +
  1277 + should 'have scraps and activities on activities' do
  1278 + another_person = fast_create(Person)
  1279 + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => profile, :content => 'A scrap'))
  1280 +
  1281 + UserStampSweeper.any_instance.stubs(:current_user).returns(profile)
  1282 + ActionTracker::Record.destroy_all
  1283 + TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')
  1284 + activity = ActionTracker::Record.last
  1285 +
  1286 + login_as(profile.identifier)
  1287 + get :index, :profile => profile.identifier
  1288 +
  1289 + assert_equivalent [scrap,activity], assigns(:activities).map {|a| a.klass.constantize.find(a.id)}
  1290 + end
1250 end 1291 end
test/unit/action_tracker_notification_test.rb
@@ -76,4 +76,12 @@ class ActionTrackerNotificationTest &lt; ActiveSupport::TestCase @@ -76,4 +76,12 @@ class ActionTrackerNotificationTest &lt; ActiveSupport::TestCase
76 assert_equal [last_notification], at.action_tracker_notifications 76 assert_equal [last_notification], at.action_tracker_notifications
77 end 77 end
78 78
  79 + should "have comments through action_tracker" do
  80 + action = fast_create(ActionTracker::Record)
  81 + notification = fast_create(ActionTrackerNotification, :action_tracker_id => action.id, :profile_id => 1)
  82 +
  83 + comment = fast_create(Comment, :source_id => action.id)
  84 + assert_equal action.comments, notification.comments
  85 + end
  86 +
79 end 87 end
test/unit/article_test.rb
@@ -1009,6 +1009,28 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1009,6 +1009,28 @@ class ArticleTest &lt; ActiveSupport::TestCase
1009 assert_equal ['a','b'], ta.get_name 1009 assert_equal ['a','b'], ta.get_name
1010 end 1010 end
1011 1011
  1012 + should 'update action when article is updated' do
  1013 + article = create(TinyMceArticle, :profile => profile)
  1014 + action = ActionTracker::Record.last
  1015 + time = action.updated_at
  1016 +
  1017 + Time.stubs(:now).returns(time + 1.day)
  1018 + article.name = 'New name'
  1019 + article.save
  1020 + assert_not_equal time, ActionTracker::Record.last.updated_at
  1021 + end
  1022 +
  1023 + should 'update action when comment is created' do
  1024 + article = create(TinyMceArticle, :profile => profile)
  1025 + action = ActionTracker::Record.last
  1026 + time = action.updated_at
  1027 +
  1028 + Time.stubs(:now).returns(time + 1.day)
  1029 +
  1030 + article.comments << Comment.create(:name => 'Guest', :email => 'guest@example.com', :title => 'test comment', :body => 'hello!')
  1031 + assert_not_equal time, ActionTracker::Record.last.updated_at
  1032 + end
  1033 +
1012 should 'notifiable is false by default' do 1034 should 'notifiable is false by default' do
1013 a = fast_create(Article) 1035 a = fast_create(Article)
1014 assert !a.notifiable? 1036 assert !a.notifiable?
@@ -1638,4 +1660,23 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -1638,4 +1660,23 @@ class ArticleTest &lt; ActiveSupport::TestCase
1638 assert_equal [c1,c2,c5], Article.text_articles 1660 assert_equal [c1,c2,c5], Article.text_articles
1639 end 1661 end
1640 1662
  1663 + should 'filter articles by date of creation' do
  1664 + from = Date.today - 2.days
  1665 + to = Date.today - 1.day
  1666 + article1 = fast_create(Article, :created_at => from - 1.day)
  1667 + article2 = fast_create(Article, :created_at => from + 6.hours)
  1668 + article3 = fast_create(Article, :created_at => to + 1.day)
  1669 +
  1670 + assert_not_includes Article.created_between(from, nil), article1
  1671 + assert_includes Article.created_between(from, nil), article2
  1672 + assert_includes Article.created_between(from, nil), article3
  1673 +
  1674 + assert_includes Article.created_between(nil, to), article1
  1675 + assert_includes Article.created_between(nil, to), article2
  1676 + assert_not_includes Article.created_between(nil, to), article3
  1677 +
  1678 + assert_not_includes Article.created_between(from, to), article1
  1679 + assert_includes Article.created_between(from, to), article2
  1680 + assert_not_includes Article.created_between(from, to), article3
  1681 + end
1641 end 1682 end
test/unit/comment_test.rb
@@ -13,13 +13,13 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -13,13 +13,13 @@ class CommentTest &lt; ActiveSupport::TestCase
13 assert_mandatory(Comment.new, :body) 13 assert_mandatory(Comment.new, :body)
14 end 14 end
15 15
16 - should 'belong to an article' do 16 + should 'have a polymorphic relationship with source' do
17 c = Comment.new 17 c = Comment.new
18 - assert_raise ActiveRecord::AssociationTypeMismatch do  
19 - c.article = 1 18 + assert_nothing_raised do
  19 + c.source = Article.new
20 end 20 end
21 assert_nothing_raised do 21 assert_nothing_raised do
22 - c.article = Article.new 22 + c.source = ActionTracker::Record.new
23 end 23 end
24 end 24 end
25 25
@@ -69,8 +69,9 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -69,8 +69,9 @@ class CommentTest &lt; ActiveSupport::TestCase
69 69
70 cc = art.comments_count 70 cc = art.comments_count
71 art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save! 71 art.comments.build(:title => 'test comment', :body => 'anything', :author => owner).save!
72 - art.reload  
73 - assert_equal cc + 1, art.comments_count 72 + art = Article.find(art.id)
  73 +
  74 + assert_equal cc + 1, Article.find(art.id).comments_count
74 end 75 end
75 76
76 should 'provide author name for authenticated authors' do 77 should 'provide author name for authenticated authors' do
@@ -217,30 +218,10 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -217,30 +218,10 @@ class CommentTest &lt; ActiveSupport::TestCase
217 assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist." 218 assert File.exists?(File.join(Rails.root, 'public', image)), "#{image} does not exist."
218 end 219 end
219 220
220 - should 'track action when comment is created' do  
221 - owner = create_user('testuser').person  
222 - article = owner.articles.create!(:name => 'test', :body => '...')  
223 - comment = article.comments.create!(:article => article, :name => 'foo', :title => 'bar', :body => 'my comment', :email => 'cracker@test.org')  
224 - ta = ActionTracker::Record.last  
225 - assert_equal 'bar', ta.get_title  
226 - assert_equal 'my comment', ta.get_body  
227 - assert_equal 'test', ta.get_article_title  
228 - assert_equal article.url, ta.get_article_url  
229 - assert_equal comment.url, ta.get_url  
230 - end  
231 -  
232 should 'have the action_tracker_target defined' do 221 should 'have the action_tracker_target defined' do
233 assert Comment.method_defined?(:action_tracker_target) 222 assert Comment.method_defined?(:action_tracker_target)
234 end 223 end
235 224
236 - should "have the action_tracker_target be the articles's profile" do  
237 - owner = create_user('testuser').person  
238 - article = owner.articles.create!(:name => 'test', :body => '...')  
239 - comment = article.comments.create!(:article => article, :name => 'foo', :title => 'bar', :body => 'my comment', :email => 'cracker@test.org')  
240 - ta = ActionTracker::Record.last  
241 - assert_equal owner, ta.target  
242 - end  
243 -  
244 should "get children of a comment" do 225 should "get children of a comment" do
245 c = fast_create(Comment) 226 c = fast_create(Comment)
246 c1 = fast_create(Comment, :reply_of_id => c.id) 227 c1 = fast_create(Comment, :reply_of_id => c.id)
@@ -307,11 +288,11 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -307,11 +288,11 @@ class CommentTest &lt; ActiveSupport::TestCase
307 288
308 should "return comments as a thread" do 289 should "return comments as a thread" do
309 a = fast_create(Article) 290 a = fast_create(Article)
310 - c0 = fast_create(Comment, :article_id => a.id)  
311 - c1 = fast_create(Comment, :reply_of_id => c0.id, :article_id => a.id)  
312 - c2 = fast_create(Comment, :reply_of_id => c1.id, :article_id => a.id)  
313 - c3 = fast_create(Comment, :reply_of_id => c0.id, :article_id => a.id)  
314 - c4 = fast_create(Comment, :article_id => a.id) 291 + c0 = fast_create(Comment, :source_id => a.id)
  292 + c1 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id)
  293 + c2 = fast_create(Comment, :reply_of_id => c1.id, :source_id => a.id)
  294 + c3 = fast_create(Comment, :reply_of_id => c0.id, :source_id => a.id)
  295 + c4 = fast_create(Comment, :source_id => a.id)
315 result = a.comments.as_thread 296 result = a.comments.as_thread
316 assert_equal c0.id, result[0].id 297 assert_equal c0.id, result[0].id
317 assert_equal [c1.id, c3.id], result[0].replies.map(&:id) 298 assert_equal [c1.id, c3.id], result[0].replies.map(&:id)
test/unit/community_test.rb
@@ -341,4 +341,5 @@ class CommunityTest &lt; ActiveSupport::TestCase @@ -341,4 +341,5 @@ class CommunityTest &lt; ActiveSupport::TestCase
341 assert_equal false, community.receives_scrap_notification? 341 assert_equal false, community.receives_scrap_notification?
342 end 342 end
343 343
  344 + should 'return tracked_actions and scraps as activities'
344 end 345 end
test/unit/enterprise_test.rb
@@ -450,4 +450,6 @@ class EnterpriseTest &lt; ActiveSupport::TestCase @@ -450,4 +450,6 @@ class EnterpriseTest &lt; ActiveSupport::TestCase
450 e = fast_create(Enterprise) 450 e = fast_create(Enterprise)
451 assert_respond_to e, :production_costs 451 assert_respond_to e, :production_costs
452 end 452 end
  453 +
  454 + should 'return tracked_actions and scraps as activities'
453 end 455 end
test/unit/person_test.rb
@@ -1243,4 +1243,34 @@ class PersonTest &lt; ActiveSupport::TestCase @@ -1243,4 +1243,34 @@ class PersonTest &lt; ActiveSupport::TestCase
1243 assert !person.visible 1243 assert !person.visible
1244 assert_not_equal password, person.user.password 1244 assert_not_equal password, person.user.password
1245 end 1245 end
  1246 +
  1247 + should 'return tracked_actions and scraps as activities' do
  1248 + person = fast_create(Person)
  1249 + another_person = fast_create(Person)
  1250 +
  1251 + scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => person, :content => 'A scrap'))
  1252 + UserStampSweeper.any_instance.expects(:current_user).returns(person).at_least_once
  1253 + TinyMceArticle.create!(:profile => person, :name => 'An article about free software')
  1254 + activity = ActionTracker::Record.last
  1255 +
  1256 + assert_equal 'An article about free software', activity.get_name.last
  1257 + assert_equal [scrap,activity], person.activities.map { |a| a.klass.constantize.find(a.id) }
  1258 + end
  1259 +
  1260 + should 'not return tracked_actions and scraps from others as activities' do
  1261 + person = fast_create(Person)
  1262 + another_person = fast_create(Person)
  1263 +
  1264 + person_scrap = Scrap.create!(defaults_for_scrap(:sender => person, :receiver => person, :content => 'A scrap from person'))
  1265 + another_person_scrap = Scrap.create!(defaults_for_scrap(:sender => another_person, :receiver => another_person, :content => 'A scrap from another person'))
  1266 +
  1267 + TinyMceArticle.create!(:profile => another_person, :name => 'An article about free software from another person')
  1268 + another_person_activity = ActionTracker::Record.last
  1269 +
  1270 + UserStampSweeper.any_instance.stubs(:current_user).returns(person)
  1271 + TinyMceArticle.create!(:profile => person, :name => 'An article about free software')
  1272 + person_activity = ActionTracker::Record.last
  1273 +
  1274 + assert_equal [person_scrap,person_activity], person.activities.map { |a| a.klass.constantize.find(a.id) }
  1275 + end
1246 end 1276 end
test/unit/profile_test.rb
@@ -1704,6 +1704,7 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1704,6 +1704,7 @@ class ProfileTest &lt; ActiveSupport::TestCase
1704 assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage) 1704 assert profile.is_on_homepage?("/#{profile.identifier}/#{homepage.slug}", homepage)
1705 end 1705 end
1706 1706
  1707 +
1707 should 'find profiles with image' do 1708 should 'find profiles with image' do
1708 env = fast_create(Environment) 1709 env = fast_create(Environment)
1709 2.times do |n| 1710 2.times do |n|
@@ -1762,10 +1763,15 @@ class ProfileTest &lt; ActiveSupport::TestCase @@ -1762,10 +1763,15 @@ class ProfileTest &lt; ActiveSupport::TestCase
1762 assert_raise NoMethodError do 1763 assert_raise NoMethodError do
1763 Profile::Roles.invalid_role(env.id) 1764 Profile::Roles.invalid_role(env.id)
1764 end 1765 end
  1766 +
  1767 + should 'return empty array as activities' do
  1768 + profile = Profile.new
  1769 + assert_equal [], profile.activities
1765 end 1770 end
1766 1771
1767 private 1772 private
1768 1773
  1774 +
1769 def assert_invalid_identifier(id) 1775 def assert_invalid_identifier(id)
1770 profile = Profile.new(:identifier => id) 1776 profile = Profile.new(:identifier => id)
1771 assert !profile.valid? 1777 assert !profile.valid?
vendor/plugins/active_record_counter_cache_on_polymorphic_association/init.rb 0 → 100644
@@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
  1 +# monkey patch to fix ActiveRecord bug
  2 +#
  3 +# https://rails.lighthouseapp.com/projects/8994/tickets/2452-counter_cache-not-updated-when-an-item-updates-its-polymorphic-owner
  4 +
  5 +ActiveRecord::Associations::ClassMethods.module_eval do
  6 +
  7 + def replace(record)
  8 + counter_cache_name = @reflection.counter_cache_column
  9 + if record.nil?
  10 + if counter_cache_name && !@owner.new_record?
  11 + record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
  12 + end
  13 + @target = @owner[@reflection.primary_key_name] = @owner[@reflection.options[:foreign_type]] = nil
  14 + else
  15 + @target = (AssociationProxy === record ? record.target : record)
  16 +
  17 + if counter_cache_name && !@owner.new_record?
  18 + record.class.base_class.increment_counter(counter_cache_name, record.id)
  19 + record.class.base_class.decrement_counter(counter_cache_name, @owner[@reflection.primary_key_name]) if @owner[@reflection.primary_key_name]
  20 + end
  21 +
  22 + @owner[@reflection.primary_key_name] = record.id
  23 + @owner[@reflection.options[:foreign_type]] = record.class.base_class.name.to_s
  24 +
  25 + @updated = true
  26 + end
  27 +
  28 + loaded
  29 + record
  30 + end
  31 +
  32 +end