This repository has been archived by the owner on May 13, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
duplicate specs for schema_auto_foreign_keys
- Loading branch information
Showing
5 changed files
with
1,475 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
require 'spec_helper' | ||
|
||
describe "Foreign Key" do | ||
|
||
let(:migration) { ::ActiveRecord::Migration } | ||
|
||
context "created with table" do | ||
before(:all) do | ||
define_schema(:auto_create => true) do | ||
create_table :users, :force => true do |t| | ||
t.string :login | ||
end | ||
create_table :comments, :force => true do |t| | ||
t.integer :user_id | ||
t.foreign_key :user_id, :users | ||
end | ||
end | ||
class User < ::ActiveRecord::Base ; end | ||
class Comment < ::ActiveRecord::Base ; end | ||
end | ||
|
||
it "should report foreign key constraints" do | ||
expect(Comment.foreign_keys.collect(&:column).flatten).to eq([ "user_id" ]) | ||
end | ||
|
||
it "should report reverse foreign key constraints" do | ||
expect(User.reverse_foreign_keys.collect(&:column).flatten).to eq([ "user_id" ]) | ||
end | ||
|
||
end | ||
|
||
context "modification" do | ||
|
||
before(:each) do | ||
define_schema(:auto_create => false) do | ||
create_table :users, :force => true do |t| | ||
t.string :login | ||
t.datetime :deleted_at | ||
end | ||
|
||
create_table :posts, :force => true do |t| | ||
t.text :body | ||
t.integer :user_id | ||
t.integer :author_id | ||
end | ||
|
||
create_table :comments, :force => true do |t| | ||
t.text :body | ||
t.integer :post_id | ||
t.foreign_key :post_id, :posts | ||
end | ||
end | ||
class User < ::ActiveRecord::Base ; end | ||
class Post < ::ActiveRecord::Base ; end | ||
class Comment < ::ActiveRecord::Base ; end | ||
Comment.reset_column_information | ||
end | ||
|
||
|
||
context "works", :sqlite3 => :skip do | ||
|
||
context "when is added", "posts(author_id)" do | ||
|
||
before(:each) do | ||
add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict) | ||
end | ||
|
||
it "references users(id)" do | ||
expect(Post).to reference(:users, :id).on(:author_id) | ||
end | ||
|
||
it "cascades on update" do | ||
expect(Post).to reference(:users).on_update(:cascade) | ||
end | ||
|
||
it "restricts on delete" do | ||
expect(Post).to reference(:users).on_delete(:restrict) | ||
end | ||
|
||
it "is available in Post.foreign_keys" do | ||
expect(Post.foreign_keys.collect(&:column)).to include('author_id') | ||
end | ||
|
||
it "is available in User.reverse_foreign_keys" do | ||
expect(User.reverse_foreign_keys.collect(&:column)).to include('author_id') | ||
end | ||
|
||
end | ||
|
||
context "when is dropped", "comments(post_id)" do | ||
|
||
let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name } | ||
|
||
before(:each) do | ||
remove_foreign_key(:comments, name: foreign_key_name) | ||
end | ||
|
||
it "doesn't reference posts(id)" do | ||
expect(Comment).not_to reference(:posts).on(:post_id) | ||
end | ||
|
||
it "is no longer available in Post.foreign_keys" do | ||
expect(Comment.foreign_keys.collect(&:column)).not_to include('post_id') | ||
end | ||
|
||
it "is no longer available in User.reverse_foreign_keys" do | ||
expect(Post.reverse_foreign_keys.collect(&:column)).not_to include('post_id') | ||
end | ||
|
||
end | ||
|
||
context "when drop using hash", "comments(post_id)" do | ||
|
||
let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name } | ||
|
||
it "finds by name" do | ||
remove_foreign_key(:comments, name: foreign_key_name) | ||
expect(Comment).not_to reference(:posts).on(:post_id) | ||
end | ||
|
||
it "finds by column_names" do | ||
remove_foreign_key(:comments, column: "post_id", to_table: "posts") | ||
expect(Comment).not_to reference(:posts).on(:post_id) | ||
end | ||
end | ||
|
||
context "when attempt to drop nonexistent foreign key" do | ||
it "raises error" do | ||
expect{remove_foreign_key(:comments, "posts", column: "nonesuch")}.to raise_error(/no foreign key/i) | ||
end | ||
|
||
it "does not error with :if_exists" do | ||
expect{remove_foreign_key(:comments, "posts", column: "nonesuch", :if_exists => true)}.to_not raise_error | ||
end | ||
end | ||
|
||
context "when referencing column and column is removed" do | ||
|
||
let(:foreign_key_name) { Comment.foreign_keys.detect { |definition| definition.column == 'post_id' }.name } | ||
|
||
it "should remove foreign keys" do | ||
remove_foreign_key(:comments, name: foreign_key_name) | ||
expect(Post.reverse_foreign_keys.collect { |fk| fk.column == 'post_id' && fk.from_table == "comments" }).to be_empty | ||
end | ||
|
||
end | ||
|
||
context "when table name is a reserved word" do | ||
before(:each) do | ||
migration.suppress_messages do | ||
migration.create_table :references, :force => true do |t| | ||
t.integer :post_id, :foreign_key => false | ||
end | ||
end | ||
end | ||
|
||
it "can add, detect, and remove a foreign key without error" do | ||
migration.suppress_messages do | ||
expect { | ||
migration.add_foreign_key(:references, :posts) | ||
foreign_key = migration.foreign_keys(:references).detect{|definition| definition.column == "post_id"} | ||
migration.remove_foreign_key(:references, name: foreign_key.name) | ||
}.to_not raise_error | ||
end | ||
end | ||
end | ||
|
||
end | ||
|
||
context "raises an exception", :sqlite3 => :only do | ||
|
||
it "when attempting to add" do | ||
expect { | ||
add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict) | ||
}.to raise_error(NotImplementedError) | ||
end | ||
|
||
it "when attempting to remove" do | ||
expect { | ||
remove_foreign_key(:posts, name: "dummy") | ||
}.to raise_error(NotImplementedError) | ||
end | ||
|
||
end | ||
end | ||
|
||
protected | ||
def add_foreign_key(*args) | ||
migration.suppress_messages do | ||
migration.add_foreign_key(*args) | ||
end | ||
User.reset_column_information | ||
Post.reset_column_information | ||
Comment.reset_column_information | ||
end | ||
|
||
def remove_foreign_key(*args) | ||
migration.suppress_messages do | ||
migration.remove_foreign_key(*args) | ||
end | ||
User.reset_column_information | ||
Post.reset_column_information | ||
Comment.reset_column_information | ||
end | ||
|
||
end |
Oops, something went wrong.