mass_insert 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. data/.gitignore +2 -0
  2. data/.travis.yml +10 -0
  3. data/Gemfile +0 -2
  4. data/README.md +15 -23
  5. data/Rakefile +22 -33
  6. data/lib/mass_insert.rb +11 -7
  7. data/lib/mass_insert/base.rb +22 -58
  8. data/lib/mass_insert/builder/adapters.rb +16 -0
  9. data/lib/mass_insert/builder/adapters/adapter.rb +65 -0
  10. data/lib/mass_insert/builder/adapters/helpers/abstract_query.rb +52 -0
  11. data/lib/mass_insert/builder/adapters/helpers/column_value.rb +90 -0
  12. data/lib/mass_insert/builder/adapters/mysql2_adapter.rb +15 -0
  13. data/lib/mass_insert/builder/adapters/postgresql_adapter.rb +7 -0
  14. data/lib/mass_insert/builder/adapters/sqlite3_adapter.rb +27 -0
  15. data/lib/mass_insert/builder/adapters/sqlserver_adapter.rb +26 -0
  16. data/lib/mass_insert/builder/base.rb +28 -0
  17. data/lib/mass_insert/builder/utilities.rb +13 -0
  18. data/lib/mass_insert/executer.rb +13 -0
  19. data/lib/mass_insert/process.rb +24 -0
  20. data/lib/mass_insert/result.rb +33 -0
  21. data/lib/mass_insert/version.rb +1 -1
  22. data/mass_insert.gemspec +2 -2
  23. data/spec/adapters/column_types/binary_spec.rb +64 -0
  24. data/spec/adapters/column_types/boolean_spec.rb +48 -0
  25. data/spec/adapters/column_types/decimal_spec.rb +59 -0
  26. data/spec/adapters/column_types/integer_spec.rb +59 -0
  27. data/spec/adapters/column_types/string_spec.rb +46 -0
  28. data/spec/{active_record_models → adapters}/model_spec.rb +1 -21
  29. data/spec/{active_record_dummy → dummy}/.gitignore +0 -0
  30. data/spec/{active_record_dummy → dummy}/Gemfile +1 -1
  31. data/spec/{active_record_dummy → dummy}/README.rdoc +0 -0
  32. data/spec/{active_record_dummy → dummy}/Rakefile +0 -0
  33. data/spec/{active_record_dummy → dummy}/app/assets/images/rails.png +0 -0
  34. data/spec/{active_record_dummy → dummy}/app/assets/javascripts/application.js +0 -0
  35. data/spec/{active_record_dummy → dummy}/app/assets/stylesheets/application.css +0 -0
  36. data/spec/{active_record_dummy → dummy}/app/controllers/application_controller.rb +0 -0
  37. data/spec/{active_record_dummy → dummy}/app/helpers/application_helper.rb +0 -0
  38. data/spec/{active_record_dummy → dummy}/app/mailers/.gitkeep +0 -0
  39. data/spec/{active_record_dummy → dummy}/app/models/.gitkeep +0 -0
  40. data/spec/{active_record_dummy → dummy}/app/models/user.rb +0 -0
  41. data/spec/{active_record_dummy → dummy}/app/views/layouts/application.html.erb +0 -0
  42. data/spec/{active_record_dummy → dummy}/config.ru +0 -0
  43. data/spec/{active_record_dummy → dummy}/config/application.rb +0 -0
  44. data/spec/{active_record_dummy → dummy}/config/boot.rb +0 -0
  45. data/spec/{active_record_dummy → dummy}/config/database.yml +3 -8
  46. data/spec/{active_record_dummy → dummy}/config/environment.rb +0 -0
  47. data/spec/{active_record_dummy → dummy}/config/environments/development.rb +0 -0
  48. data/spec/{active_record_dummy → dummy}/config/environments/mysql2.rb +0 -0
  49. data/spec/{active_record_dummy → dummy}/config/environments/postgresql.rb +0 -0
  50. data/spec/{active_record_dummy → dummy}/config/environments/production.rb +0 -0
  51. data/spec/{active_record_dummy → dummy}/config/environments/sqlite3.rb +0 -0
  52. data/spec/{active_record_dummy → dummy}/config/environments/test.rb +0 -0
  53. data/spec/{active_record_dummy → dummy}/config/initializers/backtrace_silencers.rb +0 -0
  54. data/spec/{active_record_dummy → dummy}/config/initializers/inflections.rb +0 -0
  55. data/spec/{active_record_dummy → dummy}/config/initializers/mime_types.rb +0 -0
  56. data/spec/{active_record_dummy → dummy}/config/initializers/secret_token.rb +0 -0
  57. data/spec/{active_record_dummy → dummy}/config/initializers/session_store.rb +0 -0
  58. data/spec/{active_record_dummy → dummy}/config/initializers/wrap_parameters.rb +0 -0
  59. data/spec/{active_record_dummy → dummy}/config/locales/en.yml +0 -0
  60. data/spec/{active_record_dummy → dummy}/config/routes.rb +0 -0
  61. data/spec/{active_record_dummy → dummy}/db/migrate/20130412154541_create_users.rb +0 -0
  62. data/spec/{active_record_dummy → dummy}/db/schema.rb +0 -0
  63. data/spec/{active_record_dummy → dummy}/db/seeds.rb +0 -0
  64. data/spec/{active_record_dummy → dummy}/lib/assets/.gitkeep +0 -0
  65. data/spec/{active_record_dummy → dummy}/lib/tasks/.gitkeep +0 -0
  66. data/spec/{active_record_dummy → dummy}/log/.gitkeep +0 -0
  67. data/spec/{active_record_dummy → dummy}/public/404.html +0 -0
  68. data/spec/{active_record_dummy → dummy}/public/422.html +0 -0
  69. data/spec/{active_record_dummy → dummy}/public/500.html +0 -0
  70. data/spec/{active_record_dummy → dummy}/public/favicon.ico +0 -0
  71. data/spec/{active_record_dummy → dummy}/public/index.html +0 -0
  72. data/spec/{active_record_dummy → dummy}/public/robots.txt +0 -0
  73. data/spec/{active_record_dummy → dummy}/script/rails +0 -0
  74. data/spec/{active_record_dummy → dummy}/vendor/assets/javascripts/.gitkeep +0 -0
  75. data/spec/{active_record_dummy → dummy}/vendor/assets/stylesheets/.gitkeep +0 -0
  76. data/spec/{active_record_dummy → dummy}/vendor/plugins/.gitkeep +0 -0
  77. data/spec/lib/mass_insert/base_spec.rb +40 -0
  78. data/spec/lib/mass_insert/builder/adapters/adapter_spec.rb +129 -0
  79. data/spec/lib/mass_insert/builder/adapters/helpers/abstract_query_spec.rb +130 -0
  80. data/spec/{mass_insert/adapters/adapter_helpers → lib/mass_insert/builder/adapters/helpers}/column_value_spec.rb +42 -94
  81. data/spec/lib/mass_insert/builder/adapters/mysql_adapter_spec.rb +15 -0
  82. data/spec/lib/mass_insert/builder/adapters/postgresql_adapter_spec.rb +9 -0
  83. data/spec/lib/mass_insert/builder/adapters/sqlite3_adapter_spec.rb +52 -0
  84. data/spec/lib/mass_insert/builder/adapters/sqlserver_adapter_spec.rb +38 -0
  85. data/spec/lib/mass_insert/builder/adapters_spec.rb +31 -0
  86. data/spec/lib/mass_insert/builder/base_spec.rb +28 -0
  87. data/spec/lib/mass_insert/builder/utilities_spec.rb +11 -0
  88. data/spec/lib/mass_insert/executer_spec.rb +33 -0
  89. data/spec/lib/mass_insert/process_spec.rb +44 -0
  90. data/spec/lib/mass_insert/result_spec.rb +45 -0
  91. data/spec/lib/mass_insert_spec.rb +35 -0
  92. data/spec/spec_helper.rb +7 -2
  93. data/spec/support/mass_insert_support.rb +12 -0
  94. metadata +160 -163
  95. data/lib/mass_insert/adapters.rb +0 -10
  96. data/lib/mass_insert/adapters/adapter.rb +0 -26
  97. data/lib/mass_insert/adapters/adapter_helpers.rb +0 -11
  98. data/lib/mass_insert/adapters/adapter_helpers/abstract_query.rb +0 -56
  99. data/lib/mass_insert/adapters/adapter_helpers/column_value.rb +0 -110
  100. data/lib/mass_insert/adapters/adapter_helpers/sanitizer.rb +0 -21
  101. data/lib/mass_insert/adapters/adapter_helpers/timestamp.rb +0 -33
  102. data/lib/mass_insert/adapters/mysql2_adapter.rb +0 -13
  103. data/lib/mass_insert/adapters/postgresql_adapter.rb +0 -5
  104. data/lib/mass_insert/adapters/sqlite3_adapter.rb +0 -37
  105. data/lib/mass_insert/adapters/sqlserver_adapter.rb +0 -29
  106. data/lib/mass_insert/process_control.rb +0 -46
  107. data/lib/mass_insert/query_builder.rb +0 -39
  108. data/lib/mass_insert/query_execution.rb +0 -29
  109. data/spec/active_record_models/column_types/binary_spec.rb +0 -60
  110. data/spec/active_record_models/column_types/boolean_spec.rb +0 -52
  111. data/spec/active_record_models/column_types/decimal_spec.rb +0 -49
  112. data/spec/active_record_models/column_types/integer_spec.rb +0 -49
  113. data/spec/active_record_models/column_types/string_spec.rb +0 -50
  114. data/spec/dummy_models/test.rb +0 -5
  115. data/spec/mass_insert/adapters/adapter_helpers/abstract_query_spec.rb +0 -119
  116. data/spec/mass_insert/adapters/adapter_helpers/sanitizer_spec.rb +0 -46
  117. data/spec/mass_insert/adapters/adapter_helpers/timestamp_spec.rb +0 -75
  118. data/spec/mass_insert/adapters/adapter_helpers_spec.rb +0 -24
  119. data/spec/mass_insert/adapters/adapter_spec.rb +0 -79
  120. data/spec/mass_insert/adapters/mysql_adapter_spec.rb +0 -22
  121. data/spec/mass_insert/adapters/postgresql_adapter_spec.rb +0 -11
  122. data/spec/mass_insert/adapters/sqlite3_adapter_spec.rb +0 -84
  123. data/spec/mass_insert/adapters/sqlserver_adapter_spec.rb +0 -61
  124. data/spec/mass_insert/adapters_spec.rb +0 -32
  125. data/spec/mass_insert/base_spec.rb +0 -114
  126. data/spec/mass_insert/process_control_spec.rb +0 -125
  127. data/spec/mass_insert/query_builder_spec.rb +0 -84
  128. data/spec/mass_insert/query_execution_spec.rb +0 -50
  129. data/spec/mass_insert_spec.rb +0 -28
@@ -0,0 +1,90 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Adapters
4
+ module Helpers
5
+ class ColumnValue
6
+
7
+ attr_accessor :row, :column, :class_name
8
+
9
+ def initialize row, column, class_name
10
+ @row = row
11
+ @column = column
12
+ @class_name = class_name
13
+ end
14
+
15
+ # Returns a symbol with the column type according to the database.
16
+ def column_type
17
+ class_name.columns_hash[@column.to_s].type
18
+ end
19
+
20
+ # Returns the value to this column in the row hash. The value is
21
+ # finding by symbol or string key to be most flexible.
22
+ def column_value
23
+ row.fetch(column){row[@column.to_s]}
24
+ end
25
+
26
+ # Returns the default column value and it's added to the query if
27
+ # the row hash does not contains column value.
28
+ def default_value
29
+ default_db_value ? default_db_value.to_s : "null"
30
+ end
31
+
32
+ # Returns the default database column value using methods that
33
+ # ActiveRecord provides.
34
+ def default_db_value
35
+ class_name.columns_hash[@column.to_s].default
36
+ end
37
+
38
+ # Returns the valid column value to be included in the query.
39
+ # The value depends of the database engine.
40
+ def build
41
+ column_value.nil? ? default_value : send(:"column_value_#{column_type}")
42
+ end
43
+
44
+ # Returns the correct value when column value is string, text,
45
+ # date, time, datetime, timestamp.
46
+ def column_value_string
47
+ "'#{column_value}'"
48
+ end
49
+ alias :column_value_text :column_value_string
50
+ alias :column_value_date :column_value_string
51
+ alias :column_value_time :column_value_string
52
+ alias :column_value_datetime :column_value_string
53
+ alias :column_value_timestamp :column_value_string
54
+ alias :column_value_binary :column_value_string
55
+
56
+ # Returns the correct value to integer column.
57
+ def column_value_integer
58
+ column_value.to_i.to_s
59
+ end
60
+
61
+ # Returns the correct value to decimal or float column.
62
+ def column_value_decimal
63
+ column_value.to_f.to_s
64
+ end
65
+ alias :column_value_float :column_value_decimal
66
+
67
+ # Returns the correct value to boolean column. This column calls
68
+ # the correct method according to the database adapter.
69
+ def column_value_boolean
70
+ self.send(:"#{Utilities.adapter}_column_value_boolean")
71
+ end
72
+
73
+ # Returns the column value to boolean column to mysql, postgresql
74
+ # and sqlserver databases.
75
+ def mysql2_column_value_boolean
76
+ column_value ? "true" : "false"
77
+ end
78
+ alias :postgresql_column_value_boolean :mysql2_column_value_boolean
79
+
80
+ # Returns the column value to boolean column to sqlite database.
81
+ def sqlite3_column_value_boolean
82
+ column_value ? "1" : "0"
83
+ end
84
+ alias :sqlserver_column_value_boolean :sqlite3_column_value_boolean
85
+
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,15 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Adapters
4
+ class Mysql2Adapter < Adapter
5
+
6
+ # The method is overwrited because the timestamp format to mysql
7
+ # adapter does not need accuracy with nanoseconds.
8
+ def timestamp_format
9
+ "%Y-%m-%d %H:%M:%S"
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Adapters
4
+ class PostgreSQLAdapter < Adapter; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,27 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Adapters
4
+ class SQLite3Adapter < Adapter
5
+
6
+ # Returns the amount of records to each query. Tries to take the
7
+ # each_slice option value or 500 due it's a standard in SQLite.
8
+ def values_per_insertion
9
+ each_slice || 500
10
+ end
11
+
12
+ # The method is overwrited because the queries structure to Sqlite3
13
+ # adapter are different.
14
+ def string_values
15
+ "SELECT #{string_rows_values};"
16
+ end
17
+
18
+ # The method is overwrited because the record separator to sqlite adapter
19
+ # is different.
20
+ def string_rows_values
21
+ values.map{ |row| string_single_row_values(row) }.join(" UNION SELECT ")
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Adapters
4
+ class SQLServerAdapter < Adapter
5
+
6
+ # Returns a basic part of the query with the columns definition.
7
+ def string_columns
8
+ "([#{columns.join("], [")}]) "
9
+ end
10
+
11
+ # Returns the amount of records to each query. Tries to take the
12
+ # each_slice option value or 1000 due it's a standard in SQLServer.
13
+ def values_per_insertion
14
+ each_slice || 1000
15
+ end
16
+
17
+ # The method is overwrited because the timestamp format to SQLServer
18
+ # adapter needs accuracy with three nanoseconds.
19
+ def timestamp_format
20
+ "%Y-%m-%d %H:%M:%S.%3N"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ module MassInsert
2
+ module Builder
3
+ class Base
4
+
5
+ # This function gets the correct adapter class and returns the
6
+ # sql string ready to be executed.
7
+ def build values, options
8
+ adapter_class.new(values, options).execute
9
+ end
10
+
11
+ # Returns the class of the correct database adapter according to the
12
+ # database engine that is used in Rails project.
13
+ def adapter_class
14
+ case Utilities.adapter
15
+ when "mysql2"
16
+ Adapters::Mysql2Adapter
17
+ when "postgresql"
18
+ Adapters::PostgreSQLAdapter
19
+ when "sqlite3"
20
+ Adapters::SQLite3Adapter
21
+ when "sqlserver"
22
+ Adapters::SQLServerAdapter
23
+ end
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module MassInsert
2
+ module Builder
3
+ module Utilities
4
+
5
+ # Returns a string that contains the adapter type previosly
6
+ # configured in Rails project usually in the database.yml file.
7
+ def self.adapter
8
+ ActiveRecord::Base.connection.instance_values["config"][:adapter]
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module MassInsert
2
+ # This class is responsible to execute the queries into the database.
3
+ # Uses the ActiveRecord::Base.connection.execute functionality.
4
+ class Executer
5
+
6
+ def execute queries
7
+ Array(queries).each do |query|
8
+ ActiveRecord::Base.connection.execute(query)
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ require 'benchmark'
2
+
3
+ module MassInsert
4
+ class Process
5
+
6
+ def initialize values, options
7
+ @values = values
8
+ @options = options
9
+ end
10
+
11
+ # Calls the necessary methods to complete the mass insertion process
12
+ # and the time that each method takes being executed.
13
+ def start
14
+ @building_time = Benchmark.measure do
15
+ @queries = Builder::Base.new.build(@values, @options)
16
+ end
17
+
18
+ @execution_time = Benchmark.measure do
19
+ Executer.new.execute(@queries)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,33 @@
1
+ module MassInsert
2
+ # This class is responsible to provides the mass insert process
3
+ # results according to the Process class instance.
4
+ class Result
5
+
6
+ def initialize process
7
+ @process = process
8
+ end
9
+
10
+ # Returns the time that took to create the query or queries
11
+ # string that was persisted.
12
+ def building_time
13
+ @process.instance_variable_get(:@building_time).total
14
+ end
15
+
16
+ # Returns the time that took to execute the query or queries
17
+ # string that was persisted.
18
+ def execution_time
19
+ @process.instance_variable_get(:@execution_time).total
20
+ end
21
+
22
+ # Returns the time that took to do all the MassInsert process.
23
+ def time
24
+ building_time + execution_time
25
+ end
26
+
27
+ # Returns the amount of records that were persisted.
28
+ def records
29
+ @process.instance_variable_get(:@values).count
30
+ end
31
+
32
+ end
33
+ end
@@ -1,3 +1,3 @@
1
1
  module MassInsert
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
data/mass_insert.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
8
8
  spec.version = MassInsert::VERSION
9
9
  spec.authors = ["Alejandro Gutiérrez"]
10
10
  spec.email = ["alejandrodevs@gmail.com"]
11
- spec.description = "Mass database insertion in Rails"
12
- spec.summary = "This gem aims to provide an easy and faster way to do single database insertions in Rails."
11
+ spec.summary = "Mass database insertion in Rails"
12
+ spec.description = "This gem aims to provide an easy and faster way to do single database insertions in Rails."
13
13
  spec.homepage = "https://github.com/alejandrogutierrez/mass_insert"
14
14
  spec.license = "MIT"
15
15
 
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Binary" do
4
+ let!(:values){ [{}] }
5
+ let!(:options){ Hash.new }
6
+
7
+ context "when contains binary value" do
8
+ context "when is 1" do
9
+ it "saves the value correctly" do
10
+ values.first.merge!(checked: 1)
11
+ User.mass_insert(values, options)
12
+ expect(User.last.checked).to eq("1")
13
+ end
14
+ end
15
+
16
+ context "when is 0" do
17
+ it "saves the value correctly" do
18
+ values.first.merge!(checked: 0)
19
+ User.mass_insert(values, options)
20
+ expect(User.last.checked).to eq("0")
21
+ end
22
+ end
23
+ end
24
+
25
+ context "when contains a string" do
26
+ it "converts string value to binary" do
27
+ values.first.merge!(checked: "string")
28
+ User.mass_insert(values, options)
29
+ expect(User.last.checked).to eq("string")
30
+ end
31
+ end
32
+
33
+ context "when contains a integer greater than 1" do
34
+ it "converts integer value to binary" do
35
+ values.first.merge!(checked: 150)
36
+ User.mass_insert(values, options)
37
+ expect(User.last.checked).to eq("150")
38
+ end
39
+ end
40
+
41
+ context "when contains a decimal" do
42
+ it "converts decimal value to binary" do
43
+ values.first.merge!(checked: 25.34)
44
+ User.mass_insert(values, options)
45
+ expect(User.last.checked).to eq("25.34")
46
+ end
47
+ end
48
+
49
+ context "when contains a boolean" do
50
+ it "converts boolean value to binary" do
51
+ values.first.merge!(checked: true)
52
+ User.mass_insert(values, options)
53
+ expect(User.last.checked).to eq("true")
54
+ end
55
+ end
56
+
57
+ context "when not exist in values hashes" do
58
+ it "saves the default value" do
59
+ values.first.delete(:checked)
60
+ User.mass_insert(values, options)
61
+ expect(User.last.checked).to eq(nil)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Boolean" do
4
+ let!(:values){ [{}] }
5
+ let!(:options){ Hash.new }
6
+
7
+ context "when contains boolean value" do
8
+ context "when is true" do
9
+ it "saves the true value correctly" do
10
+ values.first.merge!(active: true)
11
+ User.mass_insert(values, options)
12
+ expect(User.last.active).to eq(true)
13
+ end
14
+ end
15
+
16
+ context "when is false" do
17
+ it "saves the false value correctly" do
18
+ values.first.merge!(active: false)
19
+ User.mass_insert(values, options)
20
+ expect(User.last.active).to eq(false)
21
+ end
22
+ end
23
+ end
24
+
25
+ context "when contains a string" do
26
+ it "converts string value to boolean" do
27
+ values.first.merge!(active: "string")
28
+ User.mass_insert(values, options)
29
+ expect(User.last.active).to eq(true)
30
+ end
31
+ end
32
+
33
+ context "when contains a decimal" do
34
+ it "converts decimal value to boolean" do
35
+ values.first.merge!(active: 25.34)
36
+ User.mass_insert(values, options)
37
+ expect(User.last.active).to eq(true)
38
+ end
39
+ end
40
+
41
+ context "when not exist in values hashes" do
42
+ it "saves the default value" do
43
+ values.first.delete(:active)
44
+ User.mass_insert(values, options)
45
+ expect(User.last.active).to eq(nil)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Decimal" do
4
+ let!(:values){ [{}] }
5
+ let!(:options){ Hash.new }
6
+
7
+ context "when contains an integer" do
8
+ it "converts integer value to decimal" do
9
+ values.first.merge!(money: 10)
10
+ User.mass_insert(values, options)
11
+ expect(User.last.money).to eq(10.0)
12
+ end
13
+ end
14
+
15
+ context "when contains a string without digits" do
16
+ it "converts string value to decimal" do
17
+ values.first.merge!(money: "string")
18
+ User.mass_insert(values, options)
19
+ expect(User.last.money).to eq(0.0)
20
+ end
21
+ end
22
+
23
+ context "when contains a digits string" do
24
+ it "converts string value to decimal" do
25
+ values.first.merge!(money: "100")
26
+ User.mass_insert(values, options)
27
+ expect(User.last.money).to eq(100.0)
28
+ end
29
+
30
+ it "converts string value to decimal" do
31
+ values.first.merge!(money: "200.50")
32
+ User.mass_insert(values, options)
33
+ expect(User.last.money).to eq(200.50)
34
+ end
35
+ end
36
+
37
+ context "when contains a decimal" do
38
+ it "saves the correct value" do
39
+ values.first.merge!(money: 20.50)
40
+ User.mass_insert(values, options)
41
+ expect(User.last.money).to eq(20.50)
42
+ end
43
+ end
44
+
45
+ context "when contains a boolean" do
46
+ it "raises an exception" do
47
+ values.first.merge!(money: true)
48
+ expect(lambda{ User.mass_insert(values, options) }).to raise_exception
49
+ end
50
+ end
51
+
52
+ context "when not exist in values hashes" do
53
+ it "saves the default value" do
54
+ values.first.delete(:money)
55
+ User.mass_insert(values, options)
56
+ expect(User.last.money).to eq(nil)
57
+ end
58
+ end
59
+ end