Commit 90ea9dab by Prem Sichanugrist

Update sexy migration method names

parent ef646f3b
...@@ -4,10 +4,11 @@ require 'paperclip/schema' ...@@ -4,10 +4,11 @@ require 'paperclip/schema'
module Paperclip module Paperclip
module Glue module Glue
def self.included base #:nodoc: def self.included(base)
base.extend ClassMethods base.extend ClassMethods
base.send :include, Callbacks base.send :include, Callbacks
base.send :include, Validators base.send :include, Validators
base.send :include, Schema
base.class_attribute :attachment_definitions base.class_attribute :attachment_definitions
if defined?(ActiveRecord) if defined?(ActiveRecord)
......
require 'active_support/deprecation'
module Paperclip module Paperclip
# Provides two helpers that can be used in migrations. # Provides helper methods 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.
module Schema module Schema
@@columns = {:file_name => :string, COLUMNS = {:file_name => :string,
:content_type => :string, :content_type => :string,
:file_size => :integer, :file_size => :integer,
:updated_at => :datetime} :updated_at => :datetime}
def has_attached_file(attachment_name) def self.included(base)
with_columns_for(attachment_name) do |column_name, column_type| ActiveRecord::ConnectionAdapters::Table.send :include, TableDefinition
column(column_name, column_type) ActiveRecord::ConnectionAdapters::TableDefinition.send :include, TableDefinition
ActiveRecord::ConnectionAdapters::AbstractAdapter.send :include, Statements
end
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 end
def drop_attached_file(table_name, attachment_name) def remove_attachment(table_name, *attachment_names)
with_columns_for(attachment_name) do |column_name, column_type| raise ArgumentError, "Please specify attachment name in your remove_attachment call in your migration." if attachment_names.empty?
remove_column(table_name, column_name)
attachment_names.each do |attachment_name|
COLUMNS.each_pair do |column_name, column_type|
remove_column(table_name, "#{attachment_name}_#{column_name}", column_type)
end
end end
end end
protected 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 with_columns_for(attachment_name) module TableDefinition
@@columns.each do |suffix, column_type| def attachment(*attachment_names)
column_name = full_column_name(attachment_name, suffix) attachment_names.each do |attachment_name|
yield column_name, column_type COLUMNS.each_pair do |column_name, column_type|
column("#{attachment_name}_#{column_name}", column_type)
end
end end
end end
def full_column_name(attachment_name, column_name) def has_attached_file(*attachment_names)
"#{attachment_name}_#{column_name}".to_sym 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 end
end end
require './test/helper' require './test/helper'
require 'paperclip/schema' require 'paperclip/schema'
require 'active_support/testing/deprecation'
class MockSchema class SchemaTest < Test::Unit::TestCase
include Paperclip::Schema include ActiveSupport::Testing::Deprecation
def initialize(table_name = nil) def setup
@table_name = table_name rebuild_class
@columns = {}
@deleted_columns = []
end end
def column(name, type) def teardown
@columns[name] = type Dummy.connection.drop_table :dummies rescue nil
end end
def remove_column(table_name, column_name) context "within table definition" do
return if @table_name && @table_name != table_name context "using #has_attached_file" do
@columns.delete(column_name) should "create attachment columns" do
@deleted_columns.push(column_name) Dummy.connection.create_table :dummies, :force => true do |t|
ActiveSupport::Deprecation.silence do
t.has_attached_file :avatar
end
end end
rebuild_class
columns = Dummy.columns.map{ |column| [column.name, column.type] }
def has_column?(column_name) assert_includes columns, ['avatar_file_name', :string]
@columns.key?(column_name) assert_includes columns, ['avatar_content_type', :string]
assert_includes columns, ['avatar_file_size', :integer]
assert_includes columns, ['avatar_updated_at', :datetime]
end end
def deleted_column?(column_name) should "display deprecation warning" do
@deleted_columns.include?(column_name) Dummy.connection.create_table :dummies, :force => true do |t|
assert_deprecated do
t.has_attached_file :avatar
end
end
end
end end
def type_of(column_name) context "using #attachment" do
@columns[column_name] setup do
Dummy.connection.create_table :dummies, :force => true do |t|
t.attachment :avatar
end
rebuild_class
end end
end
class SchemaTest < Test::Unit::TestCase should "create attachment columns" do
context "Migrating up" 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 "within schema statement" do
setup do setup do
@schema = MockSchema.new Dummy.connection.create_table :dummies, :force => true
@schema.has_attached_file :avatar
end end
should "create the file_name column" do context "migrating up" do
assert @schema.has_column?(:avatar_file_name) context "with single attachment" do
setup do
Dummy.connection.add_attachment :dummies, :avatar
rebuild_class
end end
should "create the content_type column" do should "create attachment columns" do
assert @schema.has_column?(:avatar_content_type) 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
should "create the file_size column" do context "with multiple attachments" do
assert @schema.has_column?(:avatar_file_size) setup do
Dummy.connection.add_attachment :dummies, :avatar, :photo
rebuild_class
end end
should "create the updated_at column" do should "create attachment columns" do
assert @schema.has_column?(:avatar_updated_at) 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 end
should "make the file_name column a string" do context "with no attachment" do
assert_equal :string, @schema.type_of(:avatar_file_name) should "raise an error" do
assert_raise ArgumentError do
Dummy.connection.add_attachment :dummies
rebuild_class
end
end
end
end
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 end
should "make the content_type column a string" do context "using #drop_attached_file" do
assert_equal :string, @schema.type_of(:avatar_content_type) should "remove the attachment columns" do
ActiveSupport::Deprecation.silence do
Dummy.connection.drop_attached_file :dummies, :avatar
end end
rebuild_class
columns = Dummy.columns.map{ |column| [column.name, column.type] }
should "make the file_size column an integer" do assert_not_includes columns, ['avatar_file_name', :string]
assert_equal :integer, @schema.type_of(:avatar_file_size) 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
should "make the updated_at column a datetime" do should "display a deprecation warning" do
assert_equal :datetime, @schema.type_of(:avatar_updated_at) assert_deprecated do
Dummy.connection.drop_attached_file :dummies, :avatar
end
end end
end end
context "Migrating down" do context "using #remove_attachment" do
context "with single attachment" do
setup do setup do
@schema = MockSchema.new(:users) Dummy.connection.remove_attachment :dummies, :avatar
@schema.drop_attached_file :users, :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 end
should "remove the file_name column" do context "with multiple attachments" do
assert @schema.deleted_column?(:avatar_file_name) 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 end
should "remove the content_type column" do Dummy.connection.remove_attachment :dummies, :avatar, :photo
assert @schema.deleted_column?(:avatar_content_type) rebuild_class
end end
should "remove the file_size column" do should "remove the attachment columns" do
assert @schema.deleted_column?(:avatar_file_size) 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 end
should "remove the updated_at column" do context "with no attachment" do
assert @schema.deleted_column?(:avatar_updated_at) should "raise an error" do
assert_raise ArgumentError do
Dummy.connection.remove_attachment :dummies
end
end
end
end
end end
end end
end end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment