Permalink
Browse files

Update sexy migration method names

  • Loading branch information...
1 parent ef646f3 commit 90ea9dab5b81b3cf5ba91d34ab6ffb4b4c6d8af8 @sikachu sikachu committed Apr 12, 2012
Showing with 227 additions and 104 deletions.
  1. +2 −1 lib/paperclip/glue.rb
  2. +46 −26 lib/paperclip/schema.rb
  3. +179 −77 test/schema_test.rb
View
@@ -4,10 +4,11 @@
module Paperclip
module Glue
- def self.included base #:nodoc:
+ def self.included(base)
base.extend ClassMethods
base.send :include, Callbacks
base.send :include, Validators
+ base.send :include, Schema
base.class_attribute :attachment_definitions
if defined?(ActiveRecord)
View
@@ -1,39 +1,59 @@
+require 'active_support/deprecation'
+
module Paperclip
- # Provides two helpers that can be used in migrations.
- #
- # In order to use this module, the target class should implement a
- # +column+ method that takes the column name and type, both as symbols,
- # as well as a +remove_column+ method that takes a table and column name,
- # also both symbols.
+ # Provides helper methods that can be used in migrations.
module Schema
- @@columns = {:file_name => :string,
- :content_type => :string,
- :file_size => :integer,
- :updated_at => :datetime}
-
- def has_attached_file(attachment_name)
- with_columns_for(attachment_name) do |column_name, column_type|
- column(column_name, column_type)
- end
+ COLUMNS = {:file_name => :string,
+ :content_type => :string,
+ :file_size => :integer,
+ :updated_at => :datetime}
+
+ def self.included(base)
+ ActiveRecord::ConnectionAdapters::Table.send :include, TableDefinition
+ ActiveRecord::ConnectionAdapters::TableDefinition.send :include, TableDefinition
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.send :include, Statements
end
- def drop_attached_file(table_name, attachment_name)
- with_columns_for(attachment_name) do |column_name, column_type|
- remove_column(table_name, column_name)
+ module Statements
+ def add_attachment(table_name, *attachment_names)
+ raise ArgumentError, "Please specify attachment name in your add_attachment call in your migration." if attachment_names.empty?
+
+ attachment_names.each do |attachment_name|
+ COLUMNS.each_pair do |column_name, column_type|
+ add_column(table_name, "#{attachment_name}_#{column_name}", column_type)
+ end
+ end
end
- end
- protected
+ def remove_attachment(table_name, *attachment_names)
+ raise ArgumentError, "Please specify attachment name in your remove_attachment call in your migration." if attachment_names.empty?
- def with_columns_for(attachment_name)
- @@columns.each do |suffix, column_type|
- column_name = full_column_name(attachment_name, suffix)
- yield column_name, column_type
+ attachment_names.each do |attachment_name|
+ COLUMNS.each_pair do |column_name, column_type|
+ remove_column(table_name, "#{attachment_name}_#{column_name}", column_type)
@mvz

mvz Jun 18, 2012

This makes Rails try to remove the column whose name equals the value of column_type

@sikachu

sikachu Jun 18, 2012

Contributor

Thanks for catching this.

@mvz

mvz Jun 20, 2012

And thank you for fixing it so quickly!

+ end
+ end
+ end
+
+ def drop_attached_file(*args)
+ ActiveSupport::Deprecation.warn "Method `drop_attached_file` in the migration has been deprecated and will be replaced by `remove_attachment`."
+ remove_attachment(*args)
end
end
- def full_column_name(attachment_name, column_name)
- "#{attachment_name}_#{column_name}".to_sym
+ module TableDefinition
+ def attachment(*attachment_names)
+ attachment_names.each do |attachment_name|
+ COLUMNS.each_pair do |column_name, column_type|
+ column("#{attachment_name}_#{column_name}", column_type)
+ end
+ end
+ end
+
+ def has_attached_file(*attachment_names)
+ ActiveSupport::Deprecation.warn "Method `t.has_attached_file` in the migration has been deprecated and will be replaced by `t.attachment`."
+ attachment(*attachment_names)
+ end
end
end
end
View
@@ -1,98 +1,200 @@
require './test/helper'
require 'paperclip/schema'
+require 'active_support/testing/deprecation'
-class MockSchema
- include Paperclip::Schema
-
- def initialize(table_name = nil)
- @table_name = table_name
- @columns = {}
- @deleted_columns = []
- end
-
- def column(name, type)
- @columns[name] = type
- end
-
- def remove_column(table_name, column_name)
- return if @table_name && @table_name != table_name
- @columns.delete(column_name)
- @deleted_columns.push(column_name)
- end
-
- def has_column?(column_name)
- @columns.key?(column_name)
- end
+class SchemaTest < Test::Unit::TestCase
+ include ActiveSupport::Testing::Deprecation
- def deleted_column?(column_name)
- @deleted_columns.include?(column_name)
+ def setup
+ rebuild_class
end
- def type_of(column_name)
- @columns[column_name]
+ def teardown
+ Dummy.connection.drop_table :dummies rescue nil
end
-end
-
-class SchemaTest < Test::Unit::TestCase
- context "Migrating up" do
- setup do
- @schema = MockSchema.new
- @schema.has_attached_file :avatar
- end
-
- should "create the file_name column" do
- assert @schema.has_column?(:avatar_file_name)
- end
-
- should "create the content_type column" do
- assert @schema.has_column?(:avatar_content_type)
- end
-
- should "create the file_size column" do
- assert @schema.has_column?(:avatar_file_size)
- end
-
- should "create the updated_at column" do
- assert @schema.has_column?(:avatar_updated_at)
- end
- should "make the file_name column a string" do
- assert_equal :string, @schema.type_of(:avatar_file_name)
+ context "within table definition" do
+ context "using #has_attached_file" do
+ should "create attachment columns" do
+ Dummy.connection.create_table :dummies, :force => true do |t|
+ ActiveSupport::Deprecation.silence do
+ t.has_attached_file :avatar
+ end
+ end
+ rebuild_class
+
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_includes columns, ['avatar_file_name', :string]
+ assert_includes columns, ['avatar_content_type', :string]
+ assert_includes columns, ['avatar_file_size', :integer]
+ assert_includes columns, ['avatar_updated_at', :datetime]
+ end
+
+ should "display deprecation warning" do
+ Dummy.connection.create_table :dummies, :force => true do |t|
+ assert_deprecated do
+ t.has_attached_file :avatar
+ end
+ end
+ end
end
- should "make the content_type column a string" do
- assert_equal :string, @schema.type_of(:avatar_content_type)
- end
-
- should "make the file_size column an integer" do
- assert_equal :integer, @schema.type_of(:avatar_file_size)
- end
-
- should "make the updated_at column a datetime" do
- assert_equal :datetime, @schema.type_of(:avatar_updated_at)
+ context "using #attachment" do
+ setup do
+ Dummy.connection.create_table :dummies, :force => true do |t|
+ t.attachment :avatar
+ end
+ rebuild_class
+ end
+
+ should "create attachment columns" do
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_includes columns, ['avatar_file_name', :string]
+ assert_includes columns, ['avatar_content_type', :string]
+ assert_includes columns, ['avatar_file_size', :integer]
+ assert_includes columns, ['avatar_updated_at', :datetime]
+ end
end
end
- context "Migrating down" do
+ context "within schema statement" do
setup do
- @schema = MockSchema.new(:users)
- @schema.drop_attached_file :users, :avatar
- end
-
- should "remove the file_name column" do
- assert @schema.deleted_column?(:avatar_file_name)
- end
-
- should "remove the content_type column" do
- assert @schema.deleted_column?(:avatar_content_type)
+ Dummy.connection.create_table :dummies, :force => true
end
- should "remove the file_size column" do
- assert @schema.deleted_column?(:avatar_file_size)
+ context "migrating up" do
+ context "with single attachment" do
+ setup do
+ Dummy.connection.add_attachment :dummies, :avatar
+ rebuild_class
+ end
+
+ should "create attachment columns" do
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_includes columns, ['avatar_file_name', :string]
+ assert_includes columns, ['avatar_content_type', :string]
+ assert_includes columns, ['avatar_file_size', :integer]
+ assert_includes columns, ['avatar_updated_at', :datetime]
+ end
+ end
+
+ context "with multiple attachments" do
+ setup do
+ Dummy.connection.add_attachment :dummies, :avatar, :photo
+ rebuild_class
+ end
+
+ should "create attachment columns" do
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_includes columns, ['avatar_file_name', :string]
+ assert_includes columns, ['avatar_content_type', :string]
+ assert_includes columns, ['avatar_file_size', :integer]
+ assert_includes columns, ['avatar_updated_at', :datetime]
+ assert_includes columns, ['photo_file_name', :string]
+ assert_includes columns, ['photo_content_type', :string]
+ assert_includes columns, ['photo_file_size', :integer]
+ assert_includes columns, ['photo_updated_at', :datetime]
+ end
+ end
+
+ context "with no attachment" do
+ should "raise an error" do
+ assert_raise ArgumentError do
+ Dummy.connection.add_attachment :dummies
+ rebuild_class
+ end
+ end
+ end
end
- should "remove the updated_at column" do
- assert @schema.deleted_column?(:avatar_updated_at)
+ context "migrating down" do
+ setup do
+ Dummy.connection.change_table :dummies do |t|
+ t.column :avatar_file_name, :string
+ t.column :avatar_content_type, :string
+ t.column :avatar_file_size, :integer
+ t.column :avatar_updated_at, :datetime
+ end
+ end
+
+ context "using #drop_attached_file" do
+ should "remove the attachment columns" do
+ ActiveSupport::Deprecation.silence do
+ Dummy.connection.drop_attached_file :dummies, :avatar
+ end
+ rebuild_class
+
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_not_includes columns, ['avatar_file_name', :string]
+ assert_not_includes columns, ['avatar_content_type', :string]
+ assert_not_includes columns, ['avatar_file_size', :integer]
+ assert_not_includes columns, ['avatar_updated_at', :datetime]
+ end
+
+ should "display a deprecation warning" do
+ assert_deprecated do
+ Dummy.connection.drop_attached_file :dummies, :avatar
+ end
+ end
+ end
+
+ context "using #remove_attachment" do
+ context "with single attachment" do
+ setup do
+ Dummy.connection.remove_attachment :dummies, :avatar
+ rebuild_class
+ end
+
+ should "remove the attachment columns" do
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_not_includes columns, ['avatar_file_name', :string]
+ assert_not_includes columns, ['avatar_content_type', :string]
+ assert_not_includes columns, ['avatar_file_size', :integer]
+ assert_not_includes columns, ['avatar_updated_at', :datetime]
+ end
+ end
+
+ context "with multiple attachments" do
+ setup do
+ Dummy.connection.change_table :dummies do |t|
+ t.column :photo_file_name, :string
+ t.column :photo_content_type, :string
+ t.column :photo_file_size, :integer
+ t.column :photo_updated_at, :datetime
+ end
+
+ Dummy.connection.remove_attachment :dummies, :avatar, :photo
+ rebuild_class
+ end
+
+ should "remove the attachment columns" do
+ columns = Dummy.columns.map{ |column| [column.name, column.type] }
+
+ assert_not_includes columns, ['avatar_file_name', :string]
+ assert_not_includes columns, ['avatar_content_type', :string]
+ assert_not_includes columns, ['avatar_file_size', :integer]
+ assert_not_includes columns, ['avatar_updated_at', :datetime]
+ assert_not_includes columns, ['photo_file_name', :string]
+ assert_not_includes columns, ['photo_content_type', :string]
+ assert_not_includes columns, ['photo_file_size', :integer]
+ assert_not_includes columns, ['photo_updated_at', :datetime]
+ end
+ end
+
+ context "with no attachment" do
+ should "raise an error" do
+ assert_raise ArgumentError do
+ Dummy.connection.remove_attachment :dummies
+ end
+ end
+ end
+ end
end
end
end

0 comments on commit 90ea9da

Please sign in to comment.