From 4c55ce7b4549e5a8d59583f8e1dee04bd5d651f5 Mon Sep 17 00:00:00 2001 From: Alinson Santos Date: Sat, 15 Mar 2008 07:44:46 -0300 Subject: [PATCH] Refactoring: Agora o sistema se comporta bem com objetos excluidos --- app/controllers/wiki_controller.rb | 4 +-- app/models/attachment.rb | 7 ++++- app/models/course.rb | 14 +++++----- app/models/event.rb | 8 ++++-- app/models/log_entry.rb | 7 +++-- app/models/log_entry/attachment_log_entry.rb | 15 ++++------ app/models/log_entry/event_log_entry.rb | 15 ++++------ app/models/log_entry/news_log_entry.rb | 15 ++++------ app/models/log_entry/wiki_log_entry.rb | 20 +++++-------- app/models/message.rb | 27 ++++++------------ app/models/user.rb | 4 +++ app/models/wiki_page.rb | 28 +++++++++++-------- app/views/log/_wiki_log_entry.html.haml | 20 +++++++++---- app/views/wiki/versions.html.haml | 2 +- test/unit/user_test.rb | 10 +++++++ .../lib/acts_as_versioned.rb | 6 +++- 16 files changed, 110 insertions(+), 92 deletions(-) diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index c1d5993..be2f605 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -100,8 +100,8 @@ class WikiController < ApplicationController end def versions - @history_to = params[:to] || @wiki_page.versions.count - @history_from = params[:from] || @wiki_page.versions.count - 1 + @history_to = params[:to] || @wiki_page.versions[-1].version + @history_from = params[:from] || (@wiki_page.versions.count > 1 ? @wiki_page.versions[-2].version : @history_to) @offset = params[:offset] || 0 respond_to do |format| diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 87288c4..8e7e42b 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -18,9 +18,14 @@ require 'fileutils.rb' class Attachment < ActiveRecord::Base + # Plugins + acts_as_paranoid + + # Associacoes belongs_to :course + + # Validacao generate_validations - acts_as_paranoid # Atributo virtual file def file=(new_file) diff --git a/app/models/course.rb b/app/models/course.rb index 809a296..06e1393 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -16,10 +16,13 @@ class Course < ActiveRecord::Base + # Plugins + acts_as_paranoid + # Associacoes has_many :attachments, :order => "file_name", - :dependent => :destroy + :dependent => :destroy has_many :events, :order => "time asc", @@ -27,8 +30,8 @@ class Course < ActiveRecord::Base has_many :news, :foreign_key => "receiver_id", - :order => "id desc", - :dependent => :destroy + :order => "id desc", + :dependent => :destroy has_many :log_entries, :order => "created_at desc", @@ -37,10 +40,7 @@ class Course < ActiveRecord::Base has_many :wiki_pages, :order => "position", :dependent => :destroy - - # Plugins - acts_as_paranoid - + # Validacao generate_validations validates_uniqueness_of :short_name diff --git a/app/models/event.rb b/app/models/event.rb index ff94bab..cf6916e 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -15,12 +15,16 @@ # along with this program. If not, see . class Event < ActiveRecord::Base - + + # Plugins acts_as_paranoid - generate_validations + # Associacoes belongs_to :course + # Validacao + generate_validations + def Event.to_ical(courses) courses = [courses] unless courses.kind_of?(Array) cal = Icalendar::Calendar.new diff --git a/app/models/log_entry.rb b/app/models/log_entry.rb index ceb4746..f2fa95b 100644 --- a/app/models/log_entry.rb +++ b/app/models/log_entry.rb @@ -15,11 +15,14 @@ # along with this program. If not, see . class LogEntry < ActiveRecord::Base - belongs_to :user - belongs_to :course + # Plugins acts_as_paranoid + # Associacoes + belongs_to :course + belongs_to :user, :with_deleted => true + def reversible?() false end def to_xml(options = {}) diff --git a/app/models/log_entry/attachment_log_entry.rb b/app/models/log_entry/attachment_log_entry.rb index 44a00b3..f38429d 100644 --- a/app/models/log_entry/attachment_log_entry.rb +++ b/app/models/log_entry/attachment_log_entry.rb @@ -15,21 +15,18 @@ # along with this program. If not, see . class AttachmentLogEntry < LogEntry - def attachment - Attachment.find_with_deleted(target_id) - end + belongs_to :attachment, + :foreign_key => "target_id", + :with_deleted => true end class AttachmentDeleteLogEntry < AttachmentLogEntry def reversible?() - a = Attachment.find_with_deleted(target_id) - a.deleted_at != nil + attachment.deleted? end def undo!(current_user) - a = Attachment.find_with_deleted(target_id) - a.update_attribute(:deleted_at, nil) - AttachmentRestoreLogEntry.create!(:target_id => a.id, :user_id => current_user.id, - :course => a.course) + attachment.update_attribute(:deleted_at, nil) + AttachmentRestoreLogEntry.create!(:target_id => attachment.id, :user_id => current_user.id, :course => attachment.course) end end diff --git a/app/models/log_entry/event_log_entry.rb b/app/models/log_entry/event_log_entry.rb index 4937cca..45d1731 100644 --- a/app/models/log_entry/event_log_entry.rb +++ b/app/models/log_entry/event_log_entry.rb @@ -15,21 +15,18 @@ # along with this program. If not, see . class EventLogEntry < LogEntry - def event - Event.find_with_deleted(target_id) - end + belongs_to :event, + :foreign_key => "target_id", + :with_deleted => true end class EventDeleteLogEntry < EventLogEntry def reversible?() - e = Event.find_with_deleted(target_id) - e.deleted_at != nil + event.deleted? end def undo!(current_user) - e = Event.find_with_deleted(target_id) - e.update_attribute(:deleted_at, nil) - EventRestoreLogEntry.create!(:target_id => e.id, :user_id => current_user.id, - :course_id => e.course_id) + event.update_attribute(:deleted_at, nil) + EventRestoreLogEntry.create!(:target_id => event.id, :user_id => current_user.id, :course => event.course) end end diff --git a/app/models/log_entry/news_log_entry.rb b/app/models/log_entry/news_log_entry.rb index 404380c..c0196eb 100644 --- a/app/models/log_entry/news_log_entry.rb +++ b/app/models/log_entry/news_log_entry.rb @@ -15,21 +15,18 @@ # along with this program. If not, see . class NewsLogEntry < LogEntry - def news - News.find_with_deleted(target_id) - end + belongs_to :news, + :foreign_key => "target_id", + :with_deleted => true end class NewsDeleteLogEntry < NewsLogEntry def reversible?() - n = News.find_with_deleted(target_id) - n.deleted_at != nil + news.deleted? end def undo!(current_user) - n = News.find_with_deleted(target_id) - n.update_attribute(:deleted_at, nil) - NewsRestoreLogEntry.create!(:target_id => n.id, :user_id => current_user.id, - :course => n.course) + news.update_attribute(:deleted_at, nil) + NewsRestoreLogEntry.create!(:target_id => news.id, :user_id => current_user.id, :course => news.course) end end diff --git a/app/models/log_entry/wiki_log_entry.rb b/app/models/log_entry/wiki_log_entry.rb index e75ee8e..342ed6c 100644 --- a/app/models/log_entry/wiki_log_entry.rb +++ b/app/models/log_entry/wiki_log_entry.rb @@ -15,11 +15,9 @@ # along with this program. If not, see . class WikiLogEntry < LogEntry - def wiki_page - w = WikiPage.find_with_deleted(target_id) - w.revert_to(version) - return w - end + belongs_to :wiki_page, + :foreign_key => "target_id", + :with_deleted => true end class WikiEditLogEntry < WikiLogEntry @@ -28,16 +26,12 @@ end class WikiDeleteLogEntry < WikiLogEntry def reversible?() - w = WikiPage.find_with_deleted(target_id) - w.deleted_at != nil + wiki_page.deleted? end def undo!(current_user) - w = WikiPage.find_with_deleted(target_id) - w.update_attribute(:deleted_at, nil) - w.position = w.course.wiki_pages.maximum(:position) + 1 - w.save! - WikiRestoreLogEntry.create!(:target_id => w.id, :user_id => current_user.id, - :course => w.course) + wiki_page.update_attribute(:deleted_at, nil) + wiki_page.update_attribute(:position, wiki_page.course.wiki_pages.maximum(:position) + 1) + WikiRestoreLogEntry.create!(:target_id => wiki_page.id, :user_id => current_user.id, :course => wiki_page.course) end end diff --git a/app/models/message.rb b/app/models/message.rb index f3a6043..034fe45 100644 --- a/app/models/message.rb +++ b/app/models/message.rb @@ -15,28 +15,19 @@ # along with this program. If not, see . class Message < ActiveRecord::Base - acts_as_paranoid - belongs_to :user, :foreign_key => "sender_id" -end + # Plugins + acts_as_paranoid + + # Associacoes + belongs_to :user, + :foreign_key => "sender_id", + :with_deleted => true -class PrivateMessage < Message end - class News < Message validates_presence_of :title - belongs_to :course, :foreign_key => "receiver_id" -end - - -class ShoutboxMessage < Message -end - - -class CourseShoutboxMessage < ShoutboxMessage -end - - -class UserShoutboxMessage < ShoutboxMessage + belongs_to :course, + :foreign_key => "receiver_id" end diff --git a/app/models/user.rb b/app/models/user.rb index 7dda15f..ba1bcdd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -18,10 +18,13 @@ require 'digest/sha1' class User < ActiveRecord::Base + # Plugins acts_as_paranoid + # Associacoes has_and_belongs_to_many :courses, :order => 'full_name' + # Validacao validates_length_of :login, :within => 3..40 validates_length_of :name, :within => 3..40 validates_length_of :display_name, :within => 3..40 @@ -35,6 +38,7 @@ class User < ActiveRecord::Base validates_format_of :email, :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i + # Seguranca attr_protected :id, :salt attr_accessor :password, :password_confirmation diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb index e2252e1..dab96a0 100644 --- a/app/models/wiki_page.rb +++ b/app/models/wiki_page.rb @@ -19,25 +19,29 @@ require 'tempfile' class WikiPage < ActiveRecord::Base + # Plugins + acts_as_paranoid + acts_as_list :scope => 'course_id = #{course_id}' + acts_as_versioned :if_changed => [ :content, :description, :title ] + self.non_versioned_fields << 'position' + + # Associacoes belongs_to :course - belongs_to :user + belongs_to :user, :with_deleted => true + # Valicacao generate_validations validates_uniqueness_of :title, :scope => :course_id validates_format_of :title, :with => /^[^0-9]/ - acts_as_paranoid - acts_as_list :scope => 'course_id = #{course_id}' - acts_as_versioned :if_changed => [ :content, :description, :title ] - self.non_versioned_fields << 'position' - def validate - begin - to_html - rescue - errors.add("content", "possui erro de sintaxe") - end - end + def validate + begin + to_html + rescue + errors.add("content", "possui erro de sintaxe") + end + end def to_html(text = self.content) return BlueCloth.new(text).to_html diff --git a/app/views/log/_wiki_log_entry.html.haml b/app/views/log/_wiki_log_entry.html.haml index 78db92d..144042b 100644 --- a/app/views/log/_wiki_log_entry.html.haml +++ b/app/views/log/_wiki_log_entry.html.haml @@ -1,13 +1,21 @@ -= "Página " + link_to(h(entry.wiki_page.versions.last.title), course_wiki_url(entry.course, entry.wiki_page.id, :version => entry.wiki_page.version)) += "Página " + link_to(h(entry.wiki_page.title), course_wiki_url(entry.course, entry.wiki_page.id, :version => entry.version)) = "criada " if entry.kind_of?(WikiCreateLogEntry) = "editada " if entry.kind_of?(WikiEditLogEntry) = "excluída " if entry.kind_of?(WikiDeleteLogEntry) = "restaurada " if entry.kind_of?(WikiRestoreLogEntry) +- current_version = WikiPage.find_version(entry.wiki_page.id, entry.version) +- previous_version = entry.wiki_page.previous_version(entry.version) + - if entry.kind_of?(WikiEditLogEntry) - - if entry.wiki_page.description and !entry.wiki_page.description.empty? - = "(#{h(entry.wiki_page.description)})" - = "(" + link_to("diff", diff_course_wiki_url(entry.course, entry.wiki_page.id, :from => entry.wiki_page.version - 1, :to => entry.wiki_page.version)) + ")" - = "(" + link_to("edit", edit_course_wiki_url(entry.course, entry.wiki_page.id, :description => "Revertendo para versão #{entry.wiki_page.version}", :version => entry.wiki_page.version)) + ")" - = "(" + link_to("undo", edit_course_wiki_url(entry.course, entry.wiki_page.id, :description => "Revertendo para versão #{entry.wiki_page.version-1}", :version => entry.wiki_page.version - 1)) + ")" + - if current_version.description and !current_version.description.empty? + = "(#{h(current_version.description)})" + + - unless previous_version.nil? + = "(" + link_to("diff", diff_course_wiki_url(entry.course, entry.wiki_page.id, :from => previous_version.version, :to => entry.version)) + ")" + + = "(" + link_to("edit", edit_course_wiki_url(entry.course, entry.wiki_page.id, :description => "Revertendo para versão #{entry.version}", :version => entry.version)) + ")" + + - unless previous_version.nil? + = "(" + link_to("undo", edit_course_wiki_url(entry.course, entry.wiki_page.id, :description => "Revertendo para versão #{previous_version.version}", :version => previous_version.version)) + ")" diff --git a/app/views/wiki/versions.html.haml b/app/views/wiki/versions.html.haml index a778f2d..eb4d8f8 100644 --- a/app/views/wiki/versions.html.haml +++ b/app/views/wiki/versions.html.haml @@ -25,7 +25,7 @@ %td.narrow %input{:type => "radio", :name => "to", :value => entry.version, :onclick => %"history_to(#{entry.version})"} %td= link_to(tz(entry.updated_at).strftime("%d/%m/%y %H:%M:%S"), course_wiki_url(@course, @wiki_page, :version => entry.version)) - %td= link_to truncate(h(User.find(entry.user_id).display_name), 20), user_path(User.find(entry.user_id)) + %td= link_to truncate(h(User.find_with_deleted(entry.user_id).display_name), 20), user_path(User.find_with_deleted(entry.user_id)) %td = entry.description - if (entry.version > @wiki_page.versions.minimum(:version)) diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 38725f8..ec56f27 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -234,4 +234,14 @@ class UserTest < Test::Unit::TestCase assert_not_equal "I-want-to-set-my-salt", u.salt assert_equal "verybadbob", u.login end + + def test_paranoid + assert User.paranoid? + + u = users(:bob) + u.destroy + + assert_raises(ActiveRecord::RecordNotFound) { User.find(u.id) } + assert_nothing_raised { User.find_with_deleted(u.id) } + end end diff --git a/vendor/gems/acts_as_versioned-0.2.3/lib/acts_as_versioned.rb b/vendor/gems/acts_as_versioned-0.2.3/lib/acts_as_versioned.rb index 24f3b42..9b81912 100644 --- a/vendor/gems/acts_as_versioned-0.2.3/lib/acts_as_versioned.rb +++ b/vendor/gems/acts_as_versioned-0.2.3/lib/acts_as_versioned.rb @@ -279,6 +279,10 @@ module ActiveRecord #:nodoc: end end + def previous_version(current_version = self.version) + self.versions.find(:first, :conditions => [ 'version < ?', current_version ], :order => 'version desc') + end + protected # sets the new version before saving, unless you're using optimistic locking. In that case, let it take care of the version. def set_new_version @@ -394,4 +398,4 @@ module ActiveRecord #:nodoc: end end -ActiveRecord::Base.class_eval { include ActiveRecord::Acts::Versioned } \ No newline at end of file +ActiveRecord::Base.class_eval { include ActiveRecord::Acts::Versioned }