DB: Integridade referencial

master
Alinson S. Xavier 18 years ago
parent e5bc6024ba
commit c58684c31c

@ -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"
# Associacoes
has_many :attachments,
:order => "file_name",
:dependent => :destroy
has_many :shoutbox_messages,
:class_name => 'CourseShoutboxMessage',
:foreign_key => "receiver_id",
:order => 'id desc'
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 :log_entries,
:order => "created_at desc",
:dependent => :destroy
has_many :events, :order => "time asc"
has_many :wiki_pages,
:order => "position",
:dependent => :destroy
has_many :log_entries, :order => "created_at desc"
# 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,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&nbsp;de&nbsp;%B")
%td
.title= link_to h(n.title), course_news_url(@course, n)

@ -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

@ -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

@ -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
@ -27,6 +27,7 @@ ActiveRecord::Schema.define(:version => 30) do
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|

@ -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