Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Allow using cascade when truncating tables #702

Merged
merged 4 commits into from
Jul 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions db/migrations/20210710000000_add_constraint_comments.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class AddConstraintComments::V20210710000000 < Avram::Migrator::Migration::V1
def migrate
execute <<-SQL
ALTER TABLE comments
ADD CONSTRAINT fk_columns_has_post
FOREIGN KEY (post_id)
REFERENCES posts (custom_id);
SQL
end

def rollback
execute <<-SQL
ALTER TABLE comments
DROP CONSTRAINT fk_columns_has_post;
SQL
end
end
21 changes: 21 additions & 0 deletions spec/queryable_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class QueryWithDefault < User::BaseQuery
end
end

class CommentQuery < Comment::BaseQuery
end

class PostQuery < Post::BaseQuery
end

describe Avram::Queryable do
it "can chain scope methods" do
ChainedQuery.new.young.named("Paul")
Expand Down Expand Up @@ -1073,9 +1079,24 @@ describe Avram::Queryable do
it "truncates the table" do
10.times { UserFactory.create }
UserQuery.new.select_count.should eq 10
# NOTE: we don't test rows_affected here because this isn't
# available with a truncate statement
UserQuery.truncate
UserQuery.new.select_count.should eq 0
end

it "deletes associated data when cascade is true" do
post_with_matching_comment = PostFactory.create
comment = CommentFactory.new
.post_id(post_with_matching_comment.id)
.create

PostQuery.truncate cascade: true
PostQuery.new.select_count.should eq 0
expect_raises(Avram::RecordNotFoundError) do
CommentQuery.new.find(comment.id)
end
end
end

describe "#update" do
Expand Down
14 changes: 12 additions & 2 deletions src/avram/queryable.cr
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,19 @@ module Avram::Queryable(T)
new.none?
end

def self.truncate
# Removes all data from a table using the TRUNCATE postgres SQL command.
#
# You should run this command with `cascade: true` if your table
# columns are referenced by other foreign key constraints. Use *delete*
# instead if you don't want to accidentally delete rows referenced
# elsewhere.
#
# To delete all data referenced by foreign keys as well, set *cascade*
# to true.
def self.truncate(*, cascade : Bool = false)
query = self.new
query.database.exec "TRUNCATE TABLE #{query.table_name}"
cascade_str = cascade ? " CASCADE" : ""
query.database.exec "TRUNCATE TABLE #{query.table_name}#{cascade_str}"
end
end

Expand Down