DB: Integridade referencial
This commit is contained in:
@@ -34,6 +34,7 @@ class EventsController < ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@event.time = Time.now
|
||||
end
|
||||
|
||||
def create
|
||||
|
||||
@@ -25,14 +25,12 @@ class Attachment < ActiveRecord::Base
|
||||
self.size = new_file.size
|
||||
end
|
||||
|
||||
# Limpa o nome do arquivo
|
||||
protected
|
||||
def sanitize(filename)
|
||||
filename = File.basename(filename)
|
||||
filename.gsub(/[^\w\.\-]/, '_')
|
||||
end
|
||||
|
||||
# Verifica se o arquivo é válido
|
||||
def validate
|
||||
if @tmp_file
|
||||
errors.add("file") if @tmp_file.size == 0
|
||||
|
||||
@@ -13,23 +13,32 @@
|
||||
|
||||
class Course < ActiveRecord::Base
|
||||
|
||||
has_many :attachments, :order => "file_name"
|
||||
has_many :wiki_pages, :order => "position"
|
||||
|
||||
has_many :shoutbox_messages,
|
||||
:class_name => 'CourseShoutboxMessage',
|
||||
:foreign_key => "receiver_id",
|
||||
:order => 'id desc'
|
||||
# Associacoes
|
||||
has_many :attachments,
|
||||
:order => "file_name",
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :events,
|
||||
:order => "time asc",
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :news,
|
||||
:class_name => 'News',
|
||||
:foreign_key => "receiver_id",
|
||||
:order => 'id desc'
|
||||
:order => "id desc",
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :events, :order => "time asc"
|
||||
has_many :log_entries,
|
||||
:order => "created_at desc",
|
||||
:dependent => :destroy
|
||||
|
||||
has_many :log_entries, :order => "created_at desc"
|
||||
has_many :wiki_pages,
|
||||
:order => "position",
|
||||
:dependent => :destroy
|
||||
|
||||
# Plugins
|
||||
acts_as_paranoid
|
||||
|
||||
# Validacao
|
||||
generate_validations
|
||||
validates_uniqueness_of :short_name
|
||||
validates_format_of :short_name, :with => /^[^0-9]/
|
||||
@@ -41,15 +50,6 @@ class Course < ActiveRecord::Base
|
||||
end
|
||||
end
|
||||
|
||||
def after_destroy
|
||||
associations = [:attachments, :wiki_pages, :shoutbox_messages, :news, :events]
|
||||
associations.each do |assoc|
|
||||
send("#{assoc}").each do |record|
|
||||
record.destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def to_param
|
||||
self.short_name
|
||||
end
|
||||
|
||||
@@ -15,6 +15,8 @@ class LogEntry < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :course
|
||||
|
||||
acts_as_paranoid
|
||||
|
||||
def reversible?() false end
|
||||
|
||||
def to_xml(options = {})
|
||||
|
||||
@@ -31,8 +31,8 @@ class WikiDeleteLogEntry < WikiLogEntry
|
||||
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!
|
||||
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)
|
||||
end
|
||||
|
||||
@@ -31,10 +31,7 @@ class User < ActiveRecord::Base
|
||||
attr_protected :id, :salt
|
||||
attr_accessor :password, :password_confirmation
|
||||
|
||||
has_many :shoutbox_messages,
|
||||
:class_name => 'UserShoutboxMessage',
|
||||
:foreign_key => "receiver_id",
|
||||
:order => 'id desc'
|
||||
acts_as_paranoid
|
||||
|
||||
def User.find_by_login_and_pass(login, pass)
|
||||
user = find(:first, :conditions => [ "login = ?", login ])
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
%table
|
||||
- @course.news.each do |n|
|
||||
%tr[n]
|
||||
%td.top.aright
|
||||
%td.top.aright{:width => '1%'}
|
||||
= n.timestamp.strftime("%d de %B")
|
||||
%td
|
||||
.title= link_to h(n.title), course_news_url(@course, n)
|
||||
|
||||
32
db/migrate/031_create_fks.rb
Normal file
32
db/migrate/031_create_fks.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
class CreateFks < ActiveRecord::Migration
|
||||
def self.add_fk(table, fields, reference, cascade = true)
|
||||
sql = "alter table #{table} add foreign key (#{fields}) references #{reference}"
|
||||
sql = sql + " on update cascade on delete cascade" if cascade
|
||||
execute sql
|
||||
end
|
||||
|
||||
def self.up
|
||||
add_fk :attachments, :course_id, :courses
|
||||
|
||||
add_fk :courses_users, :user_id, :users
|
||||
add_fk :courses_users, :course_id, :courses
|
||||
|
||||
add_fk :events, :created_by, :users
|
||||
add_fk :events, :course_id, :courses
|
||||
|
||||
add_fk :log_entries, :course_id, :courses
|
||||
add_fk :log_entries, :user_id, :users
|
||||
|
||||
add_fk :messages, :sender_id, :users
|
||||
|
||||
add_fk :wiki_pages, :course_id, :courses
|
||||
add_fk :wiki_pages, :user_id, :users
|
||||
|
||||
add_fk :wiki_page_versions, :wiki_page_id, :wiki_pages
|
||||
add_fk :wiki_page_versions, :course_id, :courses
|
||||
add_fk :wiki_page_versions, :user_id, :users
|
||||
end
|
||||
|
||||
def self.down
|
||||
end
|
||||
end
|
||||
13
db/migrate/032_more_paranoid.rb
Normal file
13
db/migrate/032_more_paranoid.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
class MoreParanoid < ActiveRecord::Migration
|
||||
def self.up
|
||||
add_column :courses, :deleted_at, :datetime
|
||||
add_column :log_entries, :deleted_at, :datetime
|
||||
add_column :users, :deleted_at, :datetime
|
||||
end
|
||||
|
||||
def self.down
|
||||
add_column :courses, :deleted_at
|
||||
add_column :log_entries, :deleted_at
|
||||
add_column :users, :deleted_at
|
||||
end
|
||||
end
|
||||
17
db/schema.rb
17
db/schema.rb
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# It's strongly recommended to check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(:version => 30) do
|
||||
ActiveRecord::Schema.define(:version => 32) do
|
||||
|
||||
create_table "attachments", :force => true do |t|
|
||||
t.string "file_name", :null => false
|
||||
@@ -22,11 +22,12 @@ ActiveRecord::Schema.define(:version => 30) do
|
||||
end
|
||||
|
||||
create_table "courses", :force => true do |t|
|
||||
t.string "short_name", :null => false
|
||||
t.string "full_name", :null => false
|
||||
t.text "description"
|
||||
t.string "code", :default => "CK000", :null => false
|
||||
t.integer "period", :default => 1, :null => false
|
||||
t.string "short_name", :null => false
|
||||
t.string "full_name", :null => false
|
||||
t.text "description"
|
||||
t.string "code", :default => "CK000", :null => false
|
||||
t.integer "period", :default => 1, :null => false
|
||||
t.datetime "deleted_at"
|
||||
end
|
||||
|
||||
add_index "courses", ["short_name"], :name => "index_courses_on_short_name", :unique => true
|
||||
@@ -52,6 +53,7 @@ ActiveRecord::Schema.define(:version => 30) do
|
||||
t.integer "version"
|
||||
t.integer "target_id"
|
||||
t.string "type"
|
||||
t.datetime "deleted_at"
|
||||
end
|
||||
|
||||
create_table "messages", :force => true do |t|
|
||||
@@ -71,8 +73,8 @@ ActiveRecord::Schema.define(:version => 30) do
|
||||
t.datetime "updated_at"
|
||||
end
|
||||
|
||||
add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
|
||||
add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
|
||||
add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
|
||||
|
||||
create_table "users", :force => true do |t|
|
||||
t.string "login", :null => false
|
||||
@@ -88,6 +90,7 @@ ActiveRecord::Schema.define(:version => 30) do
|
||||
t.string "login_key"
|
||||
t.boolean "admin", :default => false, :null => false
|
||||
t.string "secret", :null => false
|
||||
t.datetime "deleted_at"
|
||||
end
|
||||
|
||||
create_table "wiki_page_versions", :force => true do |t|
|
||||
|
||||
4
test/fixtures/users.yml
vendored
4
test/fixtures/users.yml
vendored
@@ -21,7 +21,7 @@ bob:
|
||||
display_name: bob
|
||||
last_seen: <%= Time.now %>
|
||||
admin: true
|
||||
|
||||
secret: bob
|
||||
|
||||
existingbob:
|
||||
id: 1000002
|
||||
@@ -33,6 +33,7 @@ existingbob:
|
||||
display_name: existingbob
|
||||
last_seen: <%= Time.now %>
|
||||
admin: false
|
||||
secret: existingbob
|
||||
|
||||
longbob:
|
||||
id: 1000003
|
||||
@@ -44,3 +45,4 @@ longbob:
|
||||
display_name: longbob
|
||||
last_seen: <%= Time.now %>
|
||||
admin: false
|
||||
secret: longbob
|
||||
|
||||
@@ -17,36 +17,8 @@ class CourseTest < Test::Unit::TestCase
|
||||
|
||||
fixtures :courses
|
||||
|
||||
def test_orphaned_records
|
||||
# Escolhe um curso qualquer
|
||||
course = courses(:course_1)
|
||||
|
||||
# Cria alguns objetos associados ao curso
|
||||
attachment = Attachment.create(:file_name => 'test', :content_type => 'text/plain',
|
||||
:last_modified => Time.now, :description => 'test', :size => 1.megabyte,
|
||||
:course_id => course.id)
|
||||
|
||||
wiki_page = WikiPage.create(:title => 'teste', :course_id => course.id)
|
||||
|
||||
shoutbox_message = Message.create(:title => 'test', :body => 'test body',
|
||||
:timestamp => Time.now, :type => "CourseShoutboxMessage",
|
||||
:sender_id => 0, :receiver_id => course.id)
|
||||
|
||||
news_message = Message.create(:title => 'test', :body => 'test body',
|
||||
:timestamp => Time.now, :type => "News",
|
||||
:sender_id => 0, :receiver_id => course.id)
|
||||
|
||||
event = Event.create(:title => 'test', :time => Time.now,
|
||||
:created_by => 0, :course_id => course.id, :description => 'test')
|
||||
|
||||
# Deleta o curso
|
||||
course.destroy
|
||||
|
||||
# Ve o que aconteceu com os objetos
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Attachment.find(attachment.id) }
|
||||
assert_raises(ActiveRecord::RecordNotFound) { WikiPage.find(wiki_page.id) }
|
||||
assert_raises(ActiveRecord::RecordNotFound) { CourseShoutboxMessage.find(shoutbox_message.id) }
|
||||
assert_raises(ActiveRecord::RecordNotFound) { News.find(news_message.id) }
|
||||
assert_raises(ActiveRecord::RecordNotFound) { Event.find(event.id) }
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user