├── rails
└── init.rb
├── lib
├── enum_column_strict.rb
├── enum
│ ├── schema_definitions.rb
│ ├── quoting.rb
│ ├── mysql_adapter.rb
│ ├── schema_statements.rb
│ ├── validations.rb
│ ├── active_record_helper.rb
│ └── enum_adapter.rb
└── enum_column.rb
├── init.rb
├── test
├── fixtures
│ ├── enum_controller.rb
│ └── enumeration.rb
├── enum_controller_test.rb
├── test_helper.rb
├── db
│ └── schema.rb
└── enum_mysql_test.rb
├── LICENSE
├── enum_column.gemspec
└── README.txt
/rails/init.rb:
--------------------------------------------------------------------------------
1 | require 'enum_column'
--------------------------------------------------------------------------------
/lib/enum_column_strict.rb:
--------------------------------------------------------------------------------
1 | require 'enum_column'
--------------------------------------------------------------------------------
/init.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + "/rails/init.rb"
--------------------------------------------------------------------------------
/test/fixtures/enum_controller.rb:
--------------------------------------------------------------------------------
1 | class EnumController < ActionController::Base
2 | layout false
3 |
4 | def enum_select
5 | @test = Enumeration.new
6 | render :inline => "<%= enum_select('test', 'severity')%>"
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/lib/enum/schema_definitions.rb:
--------------------------------------------------------------------------------
1 |
2 | module ActiveRecord
3 | module ConnectionAdapters
4 | class TableDefinition
5 | def enum(*args)
6 | options = args.extract_options!
7 | column_names = args
8 | column_names.each { |name| column(name, 'enum', options) }
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/test/fixtures/enumeration.rb:
--------------------------------------------------------------------------------
1 |
2 | class Enumeration < ActiveRecord::Base
3 | validates_columns :color, :severity, :string_field, :int_field
4 | end
5 |
6 | class BasicEnum < ActiveRecord::Base
7 | validates_columns :value
8 | end
9 |
10 | class BasicDefaultEnum < ActiveRecord::Base
11 | validates_columns :value
12 | end
13 |
14 | class NonnullEnum < ActiveRecord::Base
15 | validates_columns :value
16 | end
17 |
18 | class NonnullDefaultEnum < ActiveRecord::Base
19 | validates_columns :value
20 | end
21 |
--------------------------------------------------------------------------------
/lib/enum/quoting.rb:
--------------------------------------------------------------------------------
1 | module ActiveRecord
2 | module ConnectionAdapters # :nodoc:
3 | module Quoting
4 | alias __quote_enum quote
5 |
6 | # Quote a symbol as a normal string. This will support quoting of
7 | # enumerated values.
8 | def quote(value, column = nil)
9 | if !value.is_a? Symbol
10 | __quote_enum(value, column)
11 | else
12 | ActiveRecord::Base.send(:quote_bound_value, value.to_s)
13 | end
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/enum_column.rb:
--------------------------------------------------------------------------------
1 | if defined?(::Rails::Railtie)
2 | class EnumColumnRailtie < Rails::Railtie
3 | initializer 'enum_column.initialize', :after => 'active_record.initialize_database' do |app|
4 | ActiveSupport.on_load :active_record do
5 | require 'enum/mysql_adapter'
6 | require 'enum/enum_adapter'
7 | require 'enum/schema_statements'
8 | require 'enum/schema_definitions'
9 | require 'enum/quoting'
10 | require 'enum/validations'
11 | end
12 |
13 | ActiveSupport.on_load :action_view do
14 | require 'enum/active_record_helper'
15 | end
16 | end
17 | end
18 | end
--------------------------------------------------------------------------------
/lib/enum/mysql_adapter.rb:
--------------------------------------------------------------------------------
1 | adapter_class = if defined? ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
2 | ActiveRecord::ConnectionAdapters::MySQLJdbcConnection
3 | elsif defined? ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter
4 | ActiveRecord::ConnectionAdapters::Mysql2SpatialAdapter::MainAdapter
5 | elsif defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter
6 | ActiveRecord::ConnectionAdapters::Mysql2Adapter
7 | elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
8 | ActiveRecord::ConnectionAdapters::MysqlAdapter
9 | end
10 |
11 | adapter_class.module_eval do
12 | alias __native_database_types_enum native_database_types
13 |
14 | def native_database_types #:nodoc
15 | types = __native_database_types_enum
16 | types[:enum] = { :name => "enum" }
17 | types
18 | end
19 |
20 | end
--------------------------------------------------------------------------------
/test/enum_controller_test.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/test_helper'
2 | require 'fixtures/enumeration'
3 | require 'fixtures/enum_controller'
4 |
5 | class EnumControllerTest < ActionController::TestCase
6 |
7 | def setup
8 | Enumeration.connection.execute 'DELETE FROM enumerations'
9 |
10 | Rails.application.routes.draw do
11 | match '/enum_select' => "enum#enum_select"
12 | end
13 | end
14 |
15 | test "should render enum_select" do
16 | get :enum_select
17 | assert_response :success
18 | assert_equal '', @response.body
22 | end
23 |
24 | end
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # Include the files required to test Engines.
3 |
4 | # Load the default rails test helper - this will load the environment.
5 | require File.dirname(__FILE__) + '/../../../../test/test_helper'
6 |
7 | plugin_path = File::dirname(__FILE__) + '/..'
8 | schema_file = plugin_path + "/test/db/schema.rb"
9 | load(schema_file) if File.exist?(schema_file)
10 |
11 | # set up the fixtures location to use your engine's fixtures
12 | fixture_path = File.dirname(__FILE__) + "/fixtures/"
13 | ActiveSupport::TestCase.fixture_path = fixture_path
14 | $LOAD_PATH.unshift(ActiveSupport::TestCase.fixture_path)
15 | $LOAD_PATH.unshift(File.dirname(__FILE__))
16 | # =============================================================================
17 |
18 |
19 |
--------------------------------------------------------------------------------
/test/db/schema.rb:
--------------------------------------------------------------------------------
1 |
2 | ActiveRecord::Schema.define do
3 | create_table :enumerations, :force => true do |t|
4 | t.column :severity, :enum, :limit => [:low, :medium, :high, :critical],
5 | :default => :medium
6 | t.column :color, :enum, :limit => [:red, :blue, :green, :yellow]
7 | t.column :string_field, :string, :limit => 8, :null => false
8 | t.column :int_field, :integer
9 | end
10 |
11 |
12 | create_table :basic_enums, :force => true do |t|
13 | t.column :value, :enum, :limit => [:good, :working]
14 | end
15 |
16 | create_table :basic_default_enums, :force => true do |t|
17 | t.column :value, :enum, :limit => [:good, :working],:default => :working
18 | end
19 |
20 | create_table :nonnull_enums, :force => true do |t|
21 | t.column :value, :enum, :limit => [:good, :working],:null => false
22 | end
23 |
24 | create_table :nonnull_default_enums, :force => true do |t|
25 | t.column :value, :enum, :limit => [:good, :working],:null => false,:default => :working
26 | end
27 |
28 | end
29 |
--------------------------------------------------------------------------------
/lib/enum/schema_statements.rb:
--------------------------------------------------------------------------------
1 | module ActiveRecord
2 | module ConnectionAdapters # :nodoc:
3 | module SchemaStatements
4 | alias __type_to_sql_enum type_to_sql
5 |
6 | # Add enumeration support for schema statement creation. This
7 | # will have to be adapted for every adapter if the type requires
8 | # anything by a list of allowed values. The overrides the standard
9 | # type_to_sql method and chains back to the default. This could
10 | # be done on a per adapter basis, but is generalized here.
11 | #
12 | # will generate enum('a', 'b', 'c') for :limit => [:a, :b, :c]
13 | def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
14 | if type == :enum
15 | native = native_database_types[type]
16 | column_type_sql = (native || {})[:name] || 'enum'
17 |
18 | column_type_sql << "(#{limit.map { |v| quote(v) }.join(',')})"
19 |
20 | column_type_sql
21 | else
22 | __type_to_sql_enum(type, limit, precision, scale)
23 | end
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2011 Nick Pohodnya
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/enum_column.gemspec:
--------------------------------------------------------------------------------
1 | Gem::Specification.new do |s|
2 | s.name = 'enum_column_strict'
3 | s.version = '0.0.2'
4 | s.authors = ['Nick Pohodnya', 'Aaron Weiner']
5 | s.email = 'aweiner@mdsol.com'
6 |
7 | s.files = [
8 | "README.txt",
9 | "LICENSE",
10 | "init.rb",
11 | "lib/enum_column.rb",
12 | "lib/enum_column_strict.rb",
13 | "lib/enum/active_record_helper.rb",
14 | "lib/enum/enum_adapter.rb",
15 | "lib/enum/mysql_adapter.rb",
16 | "lib/enum/quoting.rb",
17 | "lib/enum/schema_definitions.rb",
18 | "lib/enum/schema_statements.rb",
19 | "lib/enum/validations.rb"
20 | ]
21 | s.homepage = %q{http://github.com/mdsol/enum_column}
22 | s.require_paths = ["lib"]
23 | s.summary = %q{Enum type for MySQL db, without the symbol DOS vulnerability.}
24 | s.description = %q{Allows your rails models and views to take advantage of MySQL's native enum type.
25 | Forked from electronick's gem to address http://osvdb.org/show/osvdb/94679}
26 | s.test_files = [
27 | "test/test_helper.rb",
28 | "test/db/schema.rb",
29 | "test/fixtures/enumeration.rb",
30 | "test/fixtures/enum_controller.rb",
31 | "test/enum_controller_test.rb",
32 | "test/enum_mysql_test.rb"
33 | ]
34 |
35 | end
36 |
37 |
--------------------------------------------------------------------------------
/lib/enum/validations.rb:
--------------------------------------------------------------------------------
1 |
2 | module ActiveRecord
3 | module Validations
4 | module ClassMethods
5 | # Automatically validates the column against the schema definition
6 | # for nullability, format, and enumerations. Handles integers, floats,
7 | # enumerations, and string limits.
8 | #
9 | # Usage: validates_columns :severity, :name
10 | def validates_columns(*column_names)
11 | begin
12 | cols = columns_hash
13 | column_names.each do |name|
14 | col = cols[name.to_s]
15 | raise ArgumentError, "Cannot find column #{name}" unless col
16 |
17 | # test for nullability
18 | validates_presence_of(name) if !col.null
19 |
20 | # Test various known types.
21 | case col.type
22 | when :enum
23 | validates_inclusion_of name, :in => col.limit, :allow_nil => true
24 |
25 | when :integer, :float
26 | validates_numericality_of name, :allow_nil => true
27 |
28 | when :string
29 | if col.limit
30 | validates_length_of name, :maximum => col.limit, :allow_nil => true
31 | end
32 | end
33 | end
34 | rescue ActiveRecord::StatementInvalid=>e
35 | raise e unless e.message.include?("42S02") # swallow the exception if its for a missing table
36 | end
37 | end
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/lib/enum/active_record_helper.rb:
--------------------------------------------------------------------------------
1 | if defined?(Rails::Generator)
2 | module Rails
3 | module Generator
4 | class GeneratedAttribute
5 | def field_type_with_enumerated_attribute
6 | return (@field_type = :enum_select) if type == :enum
7 | field_type_without_enumerated_attribute
8 | end
9 | alias_method_chain :field_type, :enumerated_attribute
10 | end
11 | end
12 | end
13 | end
14 |
15 | if defined?(ActionView::Base)
16 | module ActionView
17 | module Helpers
18 |
19 | #form_options_helper.rb
20 | module FormOptionsHelper
21 | #def select
22 | def enum_select(object, method, options={}, html_options={})
23 | InstanceTag.new(object, method, self, options.delete(:object)).to_enum_select_tag(options, html_options)
24 | end
25 | end
26 |
27 | class InstanceTag
28 | def to_enum_select_tag(options, html_options={})
29 | if self.object.respond_to?(method_name.to_sym)
30 | column = self.object.column_for_attribute(method_name)
31 | if (value = self.object.__send__(method_name.to_sym))
32 | options[:selected] ||= value.to_s
33 | else
34 | options[:include_blank] = column.null if options[:include_blank].nil?
35 | end
36 | end
37 | to_select_tag(column.limit, options, html_options)
38 | end
39 |
40 | #initialize record_name, method, self
41 | if respond_to?(:to_tag)
42 | def to_tag_with_enumerated_attribute(options={})
43 | #look for an enum
44 | if (column_type == :enum && self.object.class.respond_to?(method_name.to_sym))
45 | to_enum_select_tag(options)
46 | else
47 | to_tag_without_enumerated_attribute(options)
48 | end
49 | end
50 | alias_method_chain :to_tag, :enumerated_attribute
51 | end
52 |
53 | end
54 |
55 | class FormBuilder
56 | def enum_select(method, options={}, html_options={})
57 | @template.enum_select(@object_name, method, objectify_options(options), @default_options.merge(html_options))
58 | end
59 | end
60 |
61 | end
62 | end
63 | end
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | Overview
2 |
3 | This gem is an extension to ActiveRecord which enables native support of enumerations in the database schema using the ENUM type in MySQL.
4 | Currently only MySQL is implemented.
5 | Tested with Rails 3. For Rails 2 the enum-column plugin serves the same functionality but is vulnerable to DOS attacks with typical use.
6 | Works with Scaffolding.
7 |
8 | Supported adapters:
9 | mysql
10 | mysql2
11 | jdbcmysql (by Nilesh Trivedi)
12 |
13 | How to use it.
14 |
15 | In your Gemfile:
16 |
17 | gem 'enum_column_strict'
18 |
19 | In your schema:
20 |
21 | When you create your schema, specify the constraint as a limit:
22 |
23 | create_table :enumerations, :force => true do |t|
24 | t.column :severity, :enum, :limit => [:low, :medium, :high, :critical], :default => :medium
25 | t.column :color, :enum, :limit => [:red, :blue, :green, :yellow]
26 | ...
27 | end
28 |
29 |
30 | In the model:
31 |
32 | You can then automatically validate this column using:
33 |
34 | validates_columns :severity, :color
35 |
36 | The rest will be handled for you. All enumerated values will be given as symbols.
37 |
38 | @e = Enumeration.new
39 | @e.severity = :medium
40 |
41 | You can always use the column reflection to get the list of possible values from the database column.
42 |
43 | Enumeration.columns_hash['color'].limit
44 | or
45 | @enumeration.column_for_attribute(:color).limit
46 |
47 | Will yield: [:red, :blue, :green, :yellow]
48 |
49 | If you assign a string to the column, it will be converted to a symbol if it's valid, and nil otherwise,
50 | so if this is the only way you populate color, validates_presence_of may be the only validation you need.
51 |
52 | Enumeration.new(:color => "red") (color will be :red)
53 | Enumeration.new(:color => "infrared") (color will be nil)
54 |
55 | In views:
56 |
57 | You can use the enum_select helper to generate input for enumerated attributes:
58 |
59 | <%= enum_select(@enumeration, 'severity')%>
60 | or
61 | <%= form_for @enumeration do |f| %>
62 | <%= f.label :severity %>
63 | <%= f.enum_select :severity %>
64 | <% end %>
65 |
66 |
--------------------------------------------------------------------------------
/lib/enum/enum_adapter.rb:
--------------------------------------------------------------------------------
1 | # This module provides all the column helper methods to deal with the
2 | # values and adds the common type management code for the adapters.
3 |
4 |
5 | # try rails 3.1, then rails 3.2+, mysql column adapters
6 | column_class = if defined? ActiveRecord::ConnectionAdapters::Mysql2Column
7 | ActiveRecord::ConnectionAdapters::Mysql2Column
8 | elsif defined? ActiveRecord::ConnectionAdapters::MysqlColumn
9 | ActiveRecord::ConnectionAdapters::MysqlColumn
10 | elsif defined? ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
11 | ActiveRecord::ConnectionAdapters::Mysql2Adapter::Column
12 | elsif defined? ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
13 | ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
14 | else
15 | ObviousHint::NoMysqlAdapterFound
16 | end
17 |
18 | column_class.module_eval do
19 |
20 | alias __klass_enum klass
21 | # The class for enum is Symbol.
22 | def klass
23 | if type == :enum
24 | Symbol
25 | else
26 | __klass_enum
27 | end
28 | end
29 |
30 | alias __type_cast_enum type_cast
31 | # Convert to a symbol.
32 | def type_cast(value)
33 | if type == :enum
34 | value.is_a?(Symbol) ? value : string_to_valid_enum(value)
35 | else
36 | __type_cast_enum(value)
37 | end
38 | end
39 |
40 | alias __type_cast_code_enum type_cast_code
41 | # Code to convert to a symbol.
42 | def type_cast_code(var_name)
43 | if type == :enum
44 | "#{var_name}.is_a?(Symbol) ? #{var_name} : #{string_to_valid_enum_hash_code}[#{var_name}]"
45 | else
46 | __type_cast_code_enum(var_name)
47 | end
48 | end
49 |
50 | private
51 | alias __simplified_type_enum simplified_type
52 | # The enum simple type.
53 | def simplified_type(field_type)
54 | if field_type =~ /enum/i
55 | :enum
56 | else
57 | __simplified_type_enum(field_type)
58 | end
59 | end
60 |
61 | alias __extract_limit_enum extract_limit
62 | def extract_limit(sql_type)
63 | if sql_type =~ /^enum/i
64 | sql_type.sub(/^enum\('(.+)'\)/i, '\1').split("','").map { |v| v.intern }
65 | else
66 | __extract_limit_enum(sql_type)
67 | end
68 | end
69 |
70 | def string_to_valid_enum(str)
71 | @valid_strings_filter ||= Hash[enum_valid_string_assoc]
72 | @valid_strings_filter[str]
73 | end
74 |
75 | def string_to_valid_enum_hash_code
76 | Hash[enum_valid_string_assoc].to_s
77 | end
78 |
79 | def enum_valid_string_assoc
80 | limit.map(&:to_s).zip(limit)
81 | end
82 |
83 | end
84 |
--------------------------------------------------------------------------------
/test/enum_mysql_test.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/test_helper'
2 | require 'fixtures/enumeration'
3 |
4 | class EnumerationsTest < Test::Unit::TestCase
5 | def setup
6 | Enumeration.connection.execute 'DELETE FROM enumerations'
7 | end
8 |
9 | def test_column_values
10 | columns = Enumeration.columns_hash
11 | color_column = columns['color']
12 | assert color_column
13 | assert_equal [:red, :blue, :green, :yellow], color_column.limit
14 |
15 | severity_column = columns['severity']
16 | assert severity_column
17 | assert_equal [:low, :medium, :high, :critical], severity_column.limit
18 | assert_equal :medium, severity_column.default
19 | end
20 |
21 | def test_insert_enum
22 | row = Enumeration.new
23 | row.color = :blue
24 | row.string_field = 'test'
25 | assert_equal :medium, row.severity
26 | assert row.save
27 |
28 | db_row = Enumeration.find(row.id)
29 | assert db_row
30 | assert_equal :blue, row.color
31 | assert_equal :medium, row.severity
32 | end
33 |
34 | # Uses the automatic validates_columns to create automatic validation rules
35 | # for columns based on the schema information.
36 | def test_bad_value
37 | row = Enumeration.new
38 | row.color = :violet
39 | row.string_field = 'test'
40 | assert !row.save
41 |
42 | assert row.errors
43 | assert_equal ['is not included in the list'], row.errors['color']
44 | end
45 |
46 | def test_other_types
47 | row = Enumeration.new
48 | row.string_field = 'a' * 10
49 | assert !row.save
50 | assert_equal ['is too long (maximum is 8 characters)'], row.errors['string_field']
51 |
52 | row = Enumeration.new
53 | assert !row.save
54 | assert_equal ['can\'t be blank'], row.errors['string_field']
55 |
56 | row = Enumeration.new
57 | row.string_field = 'test'
58 | row.int_field = 'aaaa'
59 | assert !row.save
60 | assert_equal ['is not a number'], row.errors['int_field']
61 |
62 | row = Enumeration.new
63 | row.string_field = 'test'
64 | row.int_field = '500'
65 | assert row.save
66 | end
67 |
68 | def test_view_helper
69 | request = ActionController::TestRequest.new
70 | response = ActionController::TestResponse.new
71 | request.action = 'test1'
72 | body = EnumController.process(request, response).body
73 | assert_equal '', body
74 | end
75 |
76 | def test_radio_helper
77 | request = ActionController::TestRequest.new
78 | response = ActionController::TestResponse.new
79 | request.action = 'test2'
80 | body = EnumController.process(request, response).body
81 | assert_equal '', body
82 | end
83 |
84 |
85 | # Basic tests
86 | def test_create_basic_default
87 | assert (object = BasicEnum.create)
88 | assert_nil object.value,
89 | "Enum columns without explicit default, default to null if allowed"
90 | assert !object.new_record?
91 | end
92 |
93 | def test_create_basic_good
94 | assert (object = BasicEnum.create(:value => :good))
95 | assert_equal :good, object.value
96 | assert !object.new_record?
97 | assert (object = BasicEnum.create(:value => :working))
98 | assert_equal :working, object.value
99 | assert !object.new_record?
100 | end
101 |
102 | def test_create_basic_null
103 | assert (object = BasicEnum.create(:value => nil))
104 | assert_nil object.value
105 | assert !object.new_record?
106 | end
107 |
108 | def test_create_basic_bad
109 | assert (object = BasicEnum.create(:value => :bad))
110 | assert object.new_record?
111 | end
112 |
113 | # Basic w/ Default
114 |
115 | ######################################################################
116 |
117 | def test_create_basic_wd_default
118 | assert (object = BasicDefaultEnum.create)
119 | assert_equal :working, object.value, "Explicit default ignored columns"
120 | assert !object.new_record?
121 | end
122 |
123 | def test_create_basic_wd_good
124 | assert (object = BasicDefaultEnum.create(:value => :good))
125 | assert_equal :good, object.value
126 | assert !object.new_record?
127 | assert (object = BasicDefaultEnum.create(:value => :working))
128 | assert_equal :working, object.value
129 | assert !object.new_record?
130 | end
131 |
132 | def test_create_basic_wd_null
133 | assert (object = BasicDefaultEnum.create(:value => nil))
134 | assert_nil object.value
135 | assert !object.new_record?
136 | end
137 |
138 | def test_create_basic_wd_bad
139 | assert (object = BasicDefaultEnum.create(:value => :bad))
140 | assert object.new_record?
141 | end
142 |
143 |
144 |
145 | # Nonnull
146 |
147 | ######################################################################
148 |
149 | def test_create_nonnull_default
150 | assert (object = NonnullEnum.create)
151 | # assert_equal :good, object.value,
152 | # "Enum columns without explicit default, default to first value if null not allowed"
153 | assert object.new_record?
154 | end
155 |
156 | def test_create_nonnull_good
157 | assert (object = NonnullEnum.create(:value => :good))
158 | assert_equal :good, object.value
159 | assert !object.new_record?
160 | assert (object = NonnullEnum.create(:value => :working))
161 | assert_equal :working, object.value
162 | assert !object.new_record?
163 | end
164 |
165 | def test_create_nonnull_null
166 | assert (object = NonnullEnum.create(:value => nil))
167 | assert object.new_record?
168 | end
169 |
170 | def test_create_nonnull_bad
171 | assert (object = NonnullEnum.create(:value => :bad))
172 | assert object.new_record?
173 | end
174 |
175 | # Nonnull w/ Default
176 |
177 | ######################################################################
178 |
179 | def test_create_nonnull_wd_default
180 | assert (object = NonnullDefaultEnum.create)
181 | assert_equal :working, object.value
182 | assert !object.new_record?
183 | end
184 |
185 | def test_create_nonnull_wd_good
186 | assert (object = NonnullDefaultEnum.create(:value => :good))
187 | assert_equal :good, object.value
188 | assert !object.new_record?
189 | assert (object = NonnullDefaultEnum.create(:value => :working))
190 | assert_equal :working, object.value
191 | assert !object.new_record?
192 | end
193 |
194 | def test_create_nonnull_wd_null
195 | assert (object = NonnullDefaultEnum.create(:value => nil))
196 | assert object.new_record?
197 | end
198 |
199 | def test_create_nonnull_wd_bad
200 | assert (object = NonnullDefaultEnum.create(:value => :bad))
201 | assert object.new_record?
202 | end
203 |
204 | def test_quoting
205 | value = Enumeration.send(:sanitize_sql, ["value = ? ", :"'" ] )
206 | assert_equal "value = '\\'' ", value
207 | end
208 | end
209 |
--------------------------------------------------------------------------------