has_moderated 1.0.rc4 → 1.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +28 -7
- data/Rakefile +7 -2
- data/lib/has_moderated/associations/base.rb +3 -6
- data/lib/has_moderated/moderated_attributes.rb +1 -4
- data/lib/has_moderated/moderated_create.rb +5 -4
- data/lib/has_moderated/moderated_destroy.rb +5 -2
- data/lib/has_moderated/moderation_model.rb +41 -6
- data/lib/has_moderated/moderation_preview.rb +86 -0
- data/lib/has_moderated/version.rb +1 -1
- data/lib/has_moderated.rb +1 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +72 -0
- data/test/dummy/log/test.log +119726 -0
- data/test/dummy/spec/models/photo_spec.rb +72 -13
- data/test/dummy/spec/models/task_spec.rb +244 -63
- data/test/dummy/spec/spec_helper.rb +1 -0
- data/test/dummy/spec/support/crazy_models.rb +85 -0
- data/test/dummy/spec/support/photos.rb +3 -2
- metadata +10 -31
- data/test/dummy/app/models/photo.rb +0 -4
- data/test/dummy/app/models/subtask.rb +0 -4
- data/test/dummy/app/models/task.rb +0 -3
- data/test/dummy/app/models/task_connection.rb +0 -4
- data/test/dummy/public/uploads/photo/avatar/1/test.jpg +0 -0
- data/test/dummy/public/uploads/photo/avatar/1/thumb_test.jpg +0 -0
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Add it to your project's Gemfile
|
7
7
|
|
8
|
-
gem "has_moderated"
|
8
|
+
gem "has_moderated", ">=1.0.rc4"
|
9
9
|
|
10
10
|
and run
|
11
11
|
|
@@ -28,6 +28,8 @@ When upgrading, rerun the generator
|
|
28
28
|
|
29
29
|
If there is a new migration file and you have filename conflicts, remove the old one and apply the new one, in case the schema changed. This is especially important if you are upgrading from a previous version to v1.x.
|
30
30
|
|
31
|
+
Before upgrading make sure you have reviewed and accepted/declined all current moderations first! This means the moderations table in database must be empty, otherwise the migration process will fail (on purpose). I suggest you modify the migration generated by has_moderated:install to first accept or discard all existing moderations, based on your preference - or do it in your administrative interface before deploying the upgrade.
|
32
|
+
|
31
33
|
== Why use this instead of something like Papertrail?
|
32
34
|
|
33
35
|
Papertrail and vestal_versions for example, are designed not for moderation, but for tracking changes on models. If you use Papertrail for moderating, you will always have the "newest" version in the database, while previous changes will be recorded in a special table. The problem with this for moderation is that when you are showing records, you have to read from both the model table and the "changes" table in the database, and do additional processing to combine them. This will impact performance quite a bit.
|
@@ -110,16 +112,33 @@ Do not use moderation.destroy, because discard triggers certain callbacks which
|
|
110
112
|
|
111
113
|
== Preview moderation
|
112
114
|
|
113
|
-
You can see a preview of what a moderation will do.
|
115
|
+
You can see a preview of what a moderation will do.
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
This will return the record with modified attributes, but not saved to database. You can see what changed by looking at (provided by ActiveRecord)
|
117
|
+
=== Get a read-only preview
|
118
118
|
|
119
|
-
|
119
|
+
This method allows you to retrieve a fake object which behaves like an ActiveRecord object, but is read-only.
|
120
|
+
This object allows you to see the value of all attributes, as well as all the associations (including non-moderated).
|
121
|
+
It also supports dirty tracking through ActiveModel, so you can use all its functionality (http://api.rubyonrails.org/classes/ActiveModel/Dirty.html).
|
122
|
+
|
123
|
+
preview = moderation.preview
|
124
|
+
preview.some_attr # => "new value"
|
125
|
+
preview.some_attr_change # => ["old value", "new value"]
|
126
|
+
preview.some_association.first # => #<HasModerated::FakeTask @fake_of_model=Task, @attributes={"id"=>1, "title"=>"Task 1", "desc"=>nil, "created_at"=>"2012-06-08 15:49:56.726646", "updated_at"=>"2012-06-08 15:49:56.726646"}, @changed_attributes={}, reflections.keys => [:assoc1, :assoc2]>
|
120
127
|
|
121
|
-
|
128
|
+
This preview is cached from applying the moderation in a transaction and then rolling it back (so it does not *really* affect the database).
|
129
|
+
|
130
|
+
=== Get a real ActiveRecord preview
|
122
131
|
|
132
|
+
This way, you will get a real ActiveRecord object that is really in the database. You can do whatever you want on it, however the difference is that you need to use it inside the live_preview block. This is because the moderation is applied in a transaction and after you are done using the preview, the transaction will be rolled back. I would recommend using the read-only fake object (see above) if you can, as it is safer. But sometimes you just need access to the real ActiveRecord object.
|
133
|
+
|
134
|
+
moderation.live_preview do |preview|
|
135
|
+
preview.some_attr # => "new value"
|
136
|
+
# note how we need to use .previous_changes when using live_preview,
|
137
|
+
# .changes will be blank as the record has already been saved to DB
|
138
|
+
preview.previous_changes # => {"attr"=>["old", "new"]}
|
139
|
+
preview.some_association.first # => ActiveRecord object
|
140
|
+
end
|
141
|
+
|
123
142
|
== Which kind of moderation is it?
|
124
143
|
|
125
144
|
You can call the following convenience methods to determine the type of moderation
|
@@ -227,6 +246,8 @@ It is also possible you will encounter problems with some heavily customized ass
|
|
227
246
|
|
228
247
|
This is just for my personal todo list...
|
229
248
|
|
249
|
+
improve functionality when rerunning has_moderated:install generator
|
250
|
+
|
230
251
|
hm maybe has_moderated_association could be just a has_moderated_create on the assoc? just check stuff like if task_id is not nil or something. could be much easier to implement then
|
231
252
|
|
232
253
|
also maybe use dirty https://github.com/rails/rails/blob/master/activemodel/lib/active_model/dirty.rb
|
data/Rakefile
CHANGED
@@ -23,9 +23,14 @@ end
|
|
23
23
|
Bundler::GemHelper.install_tasks
|
24
24
|
|
25
25
|
require 'rspec/core/rake_task'
|
26
|
-
|
27
26
|
RSpec::Core::RakeTask.new(:spec) do |spec|
|
27
|
+
spec.rspec_opts = %w(--color)
|
28
28
|
spec.pattern = 'test/dummy/spec{,/*/**}/*_spec.rb'
|
29
29
|
end
|
30
30
|
|
31
|
-
task :
|
31
|
+
task :prepare_test_env do
|
32
|
+
puts "Preparing test environment..."
|
33
|
+
system("cd test/dummy && RAILS_ENV=test rake db:schema:load") # db:test:prepare
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => [:spec]
|
@@ -130,12 +130,7 @@ module HasModerated
|
|
130
130
|
end
|
131
131
|
|
132
132
|
# add/delete associations to a record
|
133
|
-
def self.apply(
|
134
|
-
record = if moderation.kind_of? Moderation
|
135
|
-
moderation.moderatable
|
136
|
-
else
|
137
|
-
moderation
|
138
|
-
end
|
133
|
+
def self.apply(record, data)
|
139
134
|
associations = data[:associations]
|
140
135
|
delete_associations = data[:delete_associations]
|
141
136
|
|
@@ -154,6 +149,8 @@ module HasModerated
|
|
154
149
|
apply_delete_association(record, reflection, attrs) if attrs.present?
|
155
150
|
end
|
156
151
|
end
|
152
|
+
|
153
|
+
record
|
157
154
|
end
|
158
155
|
end # module
|
159
156
|
end
|
@@ -51,16 +51,13 @@ module HasModerated
|
|
51
51
|
end
|
52
52
|
|
53
53
|
module ApplyModeration
|
54
|
-
def self.apply(
|
54
|
+
def self.apply(rec, value)
|
55
55
|
if value[:attributes].present?
|
56
|
-
rec = moderation.moderatable
|
57
56
|
rec.without_moderation do
|
58
57
|
value[:attributes].each_pair do |attr_name, attr_value|
|
59
58
|
# bypass attr_accessible protection
|
60
59
|
rec.send(attr_name.to_s+"=", attr_value)
|
61
60
|
end
|
62
|
-
# don't run validations on save (were already ran when moderation was created)
|
63
|
-
rec.save(:validate => false) if do_save
|
64
61
|
end
|
65
62
|
end
|
66
63
|
rec
|
@@ -16,19 +16,20 @@ module HasModerated
|
|
16
16
|
end
|
17
17
|
|
18
18
|
module ApplyModeration
|
19
|
-
def self.apply(
|
19
|
+
def self.apply(klass, value)
|
20
|
+
rec = nil
|
20
21
|
if value[:create].present?
|
21
22
|
# create the main record
|
22
|
-
rec =
|
23
|
+
rec = klass.new
|
23
24
|
attrs = value[:create][:attributes]
|
24
25
|
# bypass attr_accessible protection
|
25
26
|
attrs && attrs.each_pair do |key, val|
|
26
27
|
rec.send(key.to_s+"=", val) unless key.to_s == 'id'
|
27
28
|
end
|
28
29
|
rec.without_moderation { rec.save(:validate => false) }
|
29
|
-
|
30
|
-
HasModerated::Associations::Base::ApplyModeration::apply(moderation, value[:create])
|
30
|
+
HasModerated::Associations::Base::ApplyModeration::apply(rec, value[:create])
|
31
31
|
end
|
32
|
+
rec
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
@@ -12,9 +12,12 @@ module HasModerated
|
|
12
12
|
end
|
13
13
|
|
14
14
|
module ApplyModeration
|
15
|
-
def self.apply(
|
15
|
+
def self.apply(record, value)
|
16
16
|
if value[:destroy] == true
|
17
|
-
|
17
|
+
record.without_moderation { |m| m.destroy }
|
18
|
+
nil
|
19
|
+
else
|
20
|
+
record
|
18
21
|
end
|
19
22
|
end
|
20
23
|
end
|
@@ -4,13 +4,35 @@ module HasModerated
|
|
4
4
|
@parsed_data ||= YAML::load(data)
|
5
5
|
end
|
6
6
|
|
7
|
+
def apply
|
8
|
+
if create?
|
9
|
+
record = HasModerated::ModeratedCreate::ApplyModeration::apply(moderatable_type.constantize, parsed_data)
|
10
|
+
else
|
11
|
+
record = moderatable
|
12
|
+
if record
|
13
|
+
record = HasModerated::ModeratedAttributes::ApplyModeration::apply(record, parsed_data)
|
14
|
+
record = HasModerated::Associations::Base::ApplyModeration::apply(record, parsed_data)
|
15
|
+
record = HasModerated::ModeratedDestroy::ApplyModeration::apply(record, parsed_data)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
record
|
19
|
+
end
|
20
|
+
|
21
|
+
def accept_changes(record)
|
22
|
+
if record
|
23
|
+
HasModerated::Common::try_without_moderation(record) do
|
24
|
+
# don't run validations on save (were already ran when moderation was created)
|
25
|
+
record.save(:validate => false)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
record
|
29
|
+
end
|
30
|
+
|
7
31
|
def accept
|
8
|
-
|
9
|
-
|
10
|
-
HasModerated::ModeratedAttributes::ApplyModeration::apply(self, loaded_val)
|
11
|
-
HasModerated::Associations::Base::ApplyModeration::apply(self, loaded_val)
|
12
|
-
HasModerated::ModeratedDestroy::ApplyModeration::apply(self, loaded_val)
|
32
|
+
record = apply
|
33
|
+
accept_changes(record)
|
13
34
|
self.destroy
|
35
|
+
record
|
14
36
|
end
|
15
37
|
|
16
38
|
def discard
|
@@ -21,8 +43,21 @@ module HasModerated
|
|
21
43
|
self.destroy
|
22
44
|
end
|
23
45
|
|
46
|
+
def live_preview
|
47
|
+
ActiveRecord::Base.transaction do
|
48
|
+
record = accept
|
49
|
+
yield(record)
|
50
|
+
raise ActiveRecord::Rollback
|
51
|
+
end
|
52
|
+
nil
|
53
|
+
end
|
54
|
+
|
24
55
|
def preview
|
25
|
-
|
56
|
+
fake_record = nil
|
57
|
+
live_preview do |record|
|
58
|
+
fake_record = HasModerated::Preview::from_live(record)
|
59
|
+
end
|
60
|
+
fake_record
|
26
61
|
end
|
27
62
|
|
28
63
|
def create?
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
module HasModerated
|
3
|
+
module Preview
|
4
|
+
class FakeRecord
|
5
|
+
extend ActiveModel::Naming
|
6
|
+
include ActiveModel::Conversion
|
7
|
+
include ActiveModel::Dirty
|
8
|
+
|
9
|
+
attr_accessor :attributes
|
10
|
+
|
11
|
+
def initialize(fake_of_model)
|
12
|
+
@fake_of_model = fake_of_model
|
13
|
+
end
|
14
|
+
|
15
|
+
def persisted?
|
16
|
+
false
|
17
|
+
end
|
18
|
+
|
19
|
+
def attribute name
|
20
|
+
attributes[name]
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
"#<HasModerated::Fake#{@fake_of_model.to_s}>"
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect
|
28
|
+
to_s.chomp(">") +
|
29
|
+
instance_variables.map{|name| " #{name}=#{instance_variable_get(name)}"}.join(",") +
|
30
|
+
", reflections.keys => [" + reflections.keys.map{|s| ":#{s}"}.join(", ")+ "]>"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.create_fake_association(attr_name, value, target)
|
35
|
+
target.send(:define_method, attr_name) do
|
36
|
+
value
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.resolve_record(record, cache)
|
41
|
+
return nil if record.blank?
|
42
|
+
cache[record.class] ||= Hash.new
|
43
|
+
if cache[record.class][record.id].present?
|
44
|
+
cache[record.class][record.id]
|
45
|
+
else
|
46
|
+
cache[record.class][record.id] = from_live(record, cache)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.from_live(record, object_cache = nil)
|
51
|
+
return nil if record.blank?
|
52
|
+
obj = FakeRecord.new(record.class)
|
53
|
+
eigenclass = (class << obj ; self ; end)
|
54
|
+
|
55
|
+
obj.instance_variable_set(:@attributes, record.instance_variable_get(:@attributes))
|
56
|
+
changed_attributes = Hash.new
|
57
|
+
record.previous_changes.each_pair do |attr_name, values|
|
58
|
+
changed_attributes[attr_name] = values[0]
|
59
|
+
end
|
60
|
+
obj.instance_variable_set(:@changed_attributes, changed_attributes)
|
61
|
+
|
62
|
+
# associations
|
63
|
+
object_cache ||= Hash.new
|
64
|
+
object_cache[record.class] ||= Hash.new
|
65
|
+
object_cache[record.class][record.id] = obj
|
66
|
+
eigenclass.send(:define_method, :reflections) do
|
67
|
+
record.class.reflections.reject{|k,v| k.to_sym == :moderations}
|
68
|
+
end
|
69
|
+
record.class.reflections.values.reject{|s| s.name.to_sym == :moderations}.each do |reflection|
|
70
|
+
if reflection.macro == :has_one || reflection.macro == :belongs_to
|
71
|
+
create_fake_association(
|
72
|
+
reflection.name,
|
73
|
+
resolve_record(record.send(reflection.name), object_cache),
|
74
|
+
eigenclass)
|
75
|
+
elsif reflection.collection?
|
76
|
+
create_fake_association(
|
77
|
+
reflection.name,
|
78
|
+
record.send(reflection.name).map{|r| resolve_record(r, object_cache)},
|
79
|
+
eigenclass)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
obj
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/has_moderated.rb
CHANGED
Binary file
|
data/test/dummy/db/test.sqlite3
CHANGED
Binary file
|
@@ -0,0 +1,72 @@
|
|
1
|
+
Connecting to database specified by database.yml
|
2
|
+
[1m[36m (0.2ms)[0m [1mselect sqlite_version(*)[0m
|
3
|
+
[1m[35m (1.3ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
4
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
5
|
+
[1m[35m (1.1ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
6
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
7
|
+
Connecting to database specified by database.yml
|
8
|
+
[1m[36m (1.7ms)[0m [1mselect sqlite_version(*)[0m
|
9
|
+
[1m[35m (1.5ms)[0m CREATE TABLE "moderations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "moderatable_id" integer, "moderatable_type" varchar(255), "data" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
10
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "avatar" varchar(255), "picture" varchar(255), "parentable_id" integer, "parentable_type" varchar(255), "title" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
11
|
+
[1m[35m (2.0ms)[0m CREATE TABLE "subtasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "task_id" integer, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime, "parentable_id" integer, "parentable_type" varchar(255))
|
12
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "task_connections" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "m1_id" integer, "m2_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
13
|
+
[1m[35m (1.3ms)[0m CREATE TABLE "task_photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "photo" varchar(255), "task_id" integer, "created_at" datetime, "updated_at" datetime)
|
14
|
+
[1m[36m (1.1ms)[0m [1mCREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime) [0m
|
15
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "tasks_jointable" ("m1_id" integer, "m2_id" integer)
|
16
|
+
[1m[36m (0.1ms)[0m [1mSELECT version FROM "schema_migrations"[0m
|
17
|
+
[1m[35m (2.4ms)[0m INSERT INTO "schema_migrations" (version) VALUES ('20120520215224')
|
18
|
+
[1m[36m (1.0ms)[0m [1mINSERT INTO "schema_migrations" (version) VALUES ('20120520215008')[0m
|
19
|
+
Connecting to database specified by database.yml
|
20
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
21
|
+
[1m[35m (0.4ms)[0m select sqlite_version(*)
|
22
|
+
[1m[36m (65.9ms)[0m [1mCREATE TABLE "moderations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "moderatable_id" integer, "moderatable_type" varchar(255), "data" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
23
|
+
[1m[35m (21.1ms)[0m CREATE TABLE "photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "avatar" varchar(255), "picture" varchar(255), "parentable_id" integer, "parentable_type" varchar(255), "title" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
24
|
+
[1m[36m (2.0ms)[0m [1mCREATE TABLE "subtasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "task_id" integer, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime, "parentable_id" integer, "parentable_type" varchar(255)) [0m
|
25
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "task_connections" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "m1_id" integer, "m2_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
26
|
+
[1m[36m (1.6ms)[0m [1mCREATE TABLE "task_photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "photo" varchar(255), "task_id" integer, "created_at" datetime, "updated_at" datetime) [0m
|
27
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime)
|
28
|
+
[1m[36m (2.0ms)[0m [1mCREATE TABLE "tasks_jointable" ("m1_id" integer, "m2_id" integer) [0m
|
29
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
30
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
31
|
+
[1m[35m (1.2ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
32
|
+
[1m[36m (0.1ms)[0m [1mSELECT version FROM "schema_migrations"[0m
|
33
|
+
[1m[35m (1.2ms)[0m INSERT INTO "schema_migrations" (version) VALUES ('20120520215224')
|
34
|
+
[1m[36m (2.4ms)[0m [1mINSERT INTO "schema_migrations" (version) VALUES ('20120520215008')[0m
|
35
|
+
Connecting to database specified by database.yml
|
36
|
+
[1m[36m (1.8ms)[0m [1mselect sqlite_version(*)[0m
|
37
|
+
[1m[35m (1.4ms)[0m DROP TABLE "moderations"
|
38
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "moderations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "moderatable_id" integer, "moderatable_type" varchar(255), "data" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
39
|
+
[1m[35m (1.2ms)[0m DROP TABLE "photos"
|
40
|
+
[1m[36m (1.1ms)[0m [1mCREATE TABLE "photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "avatar" varchar(255), "picture" varchar(255), "parentable_id" integer, "parentable_type" varchar(255), "title" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
41
|
+
[1m[35m (1.1ms)[0m DROP TABLE "subtasks"
|
42
|
+
[1m[36m (2.9ms)[0m [1mCREATE TABLE "subtasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "task_id" integer, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime, "parentable_id" integer, "parentable_type" varchar(255)) [0m
|
43
|
+
[1m[35m (1.2ms)[0m DROP TABLE "task_connections"
|
44
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "task_connections" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "m1_id" integer, "m2_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
45
|
+
[1m[35m (1.1ms)[0m DROP TABLE "task_photos"
|
46
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "task_photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "photo" varchar(255), "task_id" integer, "created_at" datetime, "updated_at" datetime) [0m
|
47
|
+
[1m[35m (1.1ms)[0m DROP TABLE "tasks"
|
48
|
+
[1m[36m (1.1ms)[0m [1mCREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime) [0m
|
49
|
+
[1m[35m (2.3ms)[0m DROP TABLE "tasks_jointable"
|
50
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "tasks_jointable" ("m1_id" integer, "m2_id" integer) [0m
|
51
|
+
[1m[35m (0.1ms)[0m SELECT version FROM "schema_migrations"
|
52
|
+
Connecting to database specified by database.yml
|
53
|
+
[1m[36m (0.1ms)[0m [1mSELECT "schema_migrations"."version" FROM "schema_migrations" [0m
|
54
|
+
[1m[35m (0.3ms)[0m select sqlite_version(*)
|
55
|
+
[1m[36m (1.4ms)[0m [1mCREATE TABLE "moderations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "moderatable_id" integer, "moderatable_type" varchar(255), "data" text NOT NULL, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL) [0m
|
56
|
+
[1m[35m (1.2ms)[0m CREATE TABLE "photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "avatar" varchar(255), "picture" varchar(255), "parentable_id" integer, "parentable_type" varchar(255), "title" varchar(255), "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
57
|
+
[1m[36m (1.1ms)[0m [1mCREATE TABLE "subtasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "task_id" integer, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime, "parentable_id" integer, "parentable_type" varchar(255)) [0m
|
58
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "task_connections" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "m1_id" integer, "m2_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)
|
59
|
+
[1m[36m (1.2ms)[0m [1mCREATE TABLE "task_photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "photo" varchar(255), "task_id" integer, "created_at" datetime, "updated_at" datetime) [0m
|
60
|
+
[1m[35m (1.1ms)[0m CREATE TABLE "tasks" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "title" varchar(255), "desc" varchar(255), "created_at" datetime, "updated_at" datetime)
|
61
|
+
[1m[36m (1.1ms)[0m [1mCREATE TABLE "tasks_jointable" ("m1_id" integer, "m2_id" integer) [0m
|
62
|
+
[1m[35m (1.0ms)[0m CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)
|
63
|
+
[1m[36m (0.0ms)[0m [1mPRAGMA index_list("schema_migrations")[0m
|
64
|
+
[1m[35m (1.2ms)[0m CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version")
|
65
|
+
[1m[36m (0.1ms)[0m [1mSELECT version FROM "schema_migrations"[0m
|
66
|
+
[1m[35m (1.1ms)[0m INSERT INTO "schema_migrations" (version) VALUES ('20120520215224')
|
67
|
+
[1m[36m (1.1ms)[0m [1mINSERT INTO "schema_migrations" (version) VALUES ('20120520215008')[0m
|
68
|
+
Connecting to database specified by database.yml
|
69
|
+
Connecting to database specified by database.yml
|
70
|
+
Connecting to database specified by database.yml
|
71
|
+
Connecting to database specified by database.yml
|
72
|
+
Connecting to database specified by database.yml
|