Project

General

Profile

Patch #5690 » ldappassword.patch

change user ldap password - Oskar H, 2010-06-15 14:18

View differences:

app/controllers/my_controller.rb
1
# Redmine - project management software
1
 # Redmine - project management software
2 2
# Copyright (C) 2006-2009  Jean-Philippe Lang
3 3
#
4 4
# This program is free software; you can redistribute it and/or
......
84 84
    end
85 85
    if request.post?
86 86
      if @user.check_password?(params[:password])
87
        @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
88
        if @user.save
89
          flash[:notice] = l(:notice_account_password_updated)
90
          redirect_to :action => 'account'
87
        if @user.isExternal?
88
          if @user.changeExternalPassword(params[:password],params[:new_password], params[:new_password_confirmation])
89
            flash[:notice] = l(:notice_account_password_updated)
90
            redirect_to :action => 'account'
91
          else
92
            flash[:error] = l(:notice_external_password_error)
93
          end
94
        else
95
          @user.password, @user.password_confirmation = params[:new_password], params[:new_password_confirmation]
96
          if @user.save
97
            flash[:notice] = l(:notice_account_password_updated)
98
            redirect_to :action => 'account'
99
          end
91 100
        end
92 101
      else
93 102
        flash[:error] = l(:notice_account_wrong_password)
app/models/auth_source_ldap.rb
17 17

  
18 18
require 'net/ldap'
19 19
require 'iconv'
20
require 'digest'
21
require 'base64'
20 22

  
21 23
class AuthSourceLdap < AuthSource 
22 24
  validates_presence_of :host, :port, :attr_login
......
24 26
  validates_length_of :account, :base_dn, :maximum => 255, :allow_nil => true
25 27
  validates_length_of :attr_login, :attr_firstname, :attr_lastname, :attr_mail, :maximum => 30, :allow_nil => true
26 28
  validates_numericality_of :port, :only_integer => true
27
  
29
  validates_columns :password_encryption
28 30
  before_validation :strip_ldap_attributes
29 31
  
30 32
  def after_initialize
31
    self.port = 389 if self.port == 0
33
    self.port = 389 if self.port == 0 
32 34
  end
33 35
  
34 36
  def authenticate(login, password)
......
54 56
  def auth_method_name
55 57
    "LDAP"
56 58
  end
59

  
60
  def allow_password_changes?
61
    return self.enabled_passwd
62
  end
63
  
64
  def encode_password(clear_password)
65
    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
66
    salt = ''
67
    10.times { |i| salt << chars[rand(chars.size-1)] }
68
    
69
    if self.password_encryption == :MD5
70
      logger.debug "Encode as md5"
71
      return "{MD5}"+Base64.encode64(Digest::MD5.digest(clear_password)).chomp!
72
    end
73
    if self.password_encryption == :SSHA
74
       logger.debug "Encode as ssha"
75
      return "{SSHA}"+Base64.encode64(Digest::SHA1.digest(clear_password+salt)+salt).chomp!
76
    end
77
    
78
    if self.password_encryption == :CLEAR
79
       logger.debug "Encode as cleartype"
80
      return clear_password
81
    end
82
  end
57 83
  
84
  # change password
85
  def change_password(login,password,newPassword)
86
    begin
87
      attrs = get_user_dn(login)
88
      if attrs
89
        if self.account.blank? || self.account_password.blank?
90
          logger.debug "Binding with user account"
91
          ldap_con = initialize_ldap_con(attrs[:dn], password)
92
        else
93
          logger.debug "Binding with administrator account"
94
          ldap_con = initialize_ldap_con(self.account, self.account_password)
95
        end
96
        return ldap_con.replace_attribute attrs[:dn], :userPassword, encode_password(newPassword)
97
      end
98
    rescue
99
      return false
100
    end
101
    return false
102
  end
103
    
58 104
  private
59 105
  
60 106
  def strip_ldap_attributes
app/models/user.rb
332 332
    anonymous_user
333 333
  end
334 334
  
335
  def isExternal?
336
    return auth_source_id.present?
337
  end
338
  
339
  def changeExternalPassword(password,newPassword,newPasswordConfirm)
340
    return false if newPassword == "" || newPassword.length < 4
341
    return false if newPassword != newPasswordConfirm
342
    if (self.isExternal?)
343
      return self.auth_source.change_password(self.login,password,newPassword)
344
    end
345
    return false
346
  end
347
  
335 348
  protected
336 349
  
337 350
  def validate
app/views/ldap_auth_sources/_form.rhtml
25 25

  
26 26
<p><label for="auth_source_onthefly_register"><%=l(:field_onthefly)%></label>
27 27
<%= check_box 'auth_source', 'onthefly_register' %></p>
28
<p><label for="auth_source_enabled_passwd"><%=l(:field_enabled_passwd)%></label>
29
<%= check_box 'auth_source', 'enabled_passwd' %></p>
28 30
</div>
29 31

  
30 32
<fieldset class="box"><legend><%=l(:label_attribute_plural)%></legend>
......
39 41

  
40 42
<p><label for="auth_source_attr_mail"><%=l(:field_mail)%></label>
41 43
<%= text_field 'auth_source', 'attr_mail', :size => 20  %></p>
44

  
45
<p><label for="auth_source_password_encryption"><%=l(:field_password_encryption)%></label>
46
<%= input 'auth_source', 'password_encryption' %></p>
42 47
</fieldset>
43 48
<!--[eoform:auth_source]-->
44 49

  
config/locales/de.yml
150 150
  general_pdf_encoding: ISO-8859-1
151 151
  general_first_day_of_week: '1'
152 152

  
153
  notice_external_password_error: Externes Konto konnte nicht aktualisiert werden.
153 154
  notice_account_updated: Konto wurde erfolgreich aktualisiert.
154 155
  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungültig.
155 156
  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
156 157
  notice_account_wrong_password: Falsches Kennwort.
157 158
  notice_account_register_done: Konto wurde erfolgreich angelegt.
158 159
  notice_account_unknown_email: Unbekannter Benutzer.
159
  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. Unmöglich, das Kennwort zu ändern.
160
  notice_can_t_change_password: Kennwort ändern ist gesperrt für diese externe Authentifizierungs-Quelle.
160 161
  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wählen, wurde Ihnen geschickt.
161 162
  notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
162 163
  notice_successful_create: Erfolgreich angelegt
......
273 274
  field_attr_lastname: Name-Attribut
274 275
  field_attr_mail: E-Mail-Attribut
275 276
  field_onthefly: On-the-fly-Benutzererstellung
277
  field_password_encryption: Verschlüsselungsart
278
  field_enabled_passwd: Password ändern erlauben
276 279
  field_start_date: Beginn
277 280
  field_done_ratio: % erledigt
278 281
  field_auth_source: Authentifizierungs-Modus
config/locales/en.yml
127 127
  general_pdf_encoding: ISO-8859-1
128 128
  general_first_day_of_week: '7'
129 129
  
130
  notice_external_password_error: External password changing goes wrong
130 131
  notice_account_updated: Account was successfully updated.
131 132
  notice_account_invalid_creditentials: Invalid user or password
132 133
  notice_account_password_updated: Password was successfully updated.
......
253 254
  field_attr_lastname: Lastname attribute
254 255
  field_attr_mail: Email attribute
255 256
  field_onthefly: On-the-fly user creation
257
  field_password_encryption: Encyrption
258
  field_enabled_passwd: Enabled password changing
256 259
  field_start_date: Start
257 260
  field_done_ratio: % Done
258 261
  field_auth_source: Authentication mode
db/migrate/20100609104539_ldap_password_change.rb
1
class LdapPasswordChange < ActiveRecord::Migration
2
  def self.up
3
      add_column :auth_sources,  :password_encryption, :enum, :limit => [:MD5, :SSHA, :CLEAR], :default => :MD5
4
      add_column :auth_sources,  :enabled_passwd, :boolean, :default => false
5
  end
6

  
7
  def self.down
8
    remove_column :auth_sources, :password_encryption
9
    remove_column :auth_sources, :enabled_passwd
10
  end
11
end
vendor/plugins/enum-column/init.rb
1
require 'enum/enum_adapter'
2
require 'enum/mysql_adapter' if defined? ActiveRecord::ConnectionAdapters::MysqlAdapter
3
require 'enum/postgresql_adapter' if defined? ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
4
require 'enum/sqlite3_adapter' if defined? ActiveRecord::ConnectionAdapters::SQLite3Adapter
5
require 'enum/schema_statements'
6
require 'enum/schema_definitions'
7
require 'enum/quoting'
8
require 'enum/validations'
9
require 'enum/active_record_helper'
vendor/plugins/enum-column/lib/enum/active_record_helper.rb
1

  
2
module ActionView
3
  module Helpers
4
    module FormHelper
5
      # helper to create a select drop down list for the enumerated values. This
6
      # is the default input tag.
7
      def enum_select(object_name, method, options = {})
8
        if RAILS_GEM_VERSION < '2.2.0'
9
          tag = InstanceTag.new(object_name, method, self, nil, options.delete(:object))
10
        else
11
          tag = InstanceTag.new(object_name, method, self, options.delete(:object))
12
        end
13
        tag.to_enum_select_tag(options)
14
      end
15

  
16
      # Creates a set of radio buttons for all the enumerated values.
17
      def enum_radio(object_name, method, options = {})
18
        if RAILS_GEM_VERSION < '2.2.0'
19
          tag = InstanceTag.new(object_name, method, self, nil, options.delete(:object))
20
        else
21
          tag = InstanceTag.new(object_name, method, self, options.delete(:object))
22
        end
23
        tag.to_enum_radio_tag(options)        
24
      end
25
    end
26

  
27
    class FormBuilder
28
      def enum_select(method, options = { })
29
        @template.enum_select(@object_name, method, options)
30
      end
31

  
32
      def enum_radio(method, options = { })
33
        @template.enum_radio(@object_name, method, options)
34
      end
35
    end
36
    
37
    class InstanceTag #:nodoc:
38
      alias __to_tag_enum to_tag
39

  
40
      # Add the enumeration tag support. Defaults using the select tag to
41
      # display the options.
42
      def to_tag(options = {})
43
        if column_type == :enum
44
          to_enum_select_tag(options)
45
        else
46
          __to_tag_enum(options)
47
        end
48
      end
49

  
50
      # Create a select tag and one option for each of the
51
      # enumeration values.
52
      def to_enum_select_tag(options = {})
53
        # Remove when we no longer support 1.1.
54
        begin
55
          v = value(object)
56
        rescue ArgumentError
57
          v = value
58
        end
59
        add_default_name_and_id(options)
60
        tag_text = "<select"
61
        tag_text << tag_options(options)
62
        tag_text << ">"
63
        values = enum_values
64
        raise ArgumentError, "No values for enum select tag" unless values
65
        if options[:include_blank]
66
          tag_text << "<option value=\"\"></option>\n"
67
        end
68
        values.each do |enum|
69
          tag_text << "<option value=\"#{enum}\""
70
          tag_text << ' selected="selected"' if v and v == enum
71
          tag_text << ">#{enum}</option>"
72
        end
73
        tag_text << "</select>"
74
      end
75

  
76
      # Creates a set of radio buttons and labels.
77
      def to_enum_radio_tag(options = {})
78
        # Remove when we no longer support 1.1.
79
        begin
80
          v = value(object)
81
        rescue ArgumentError
82
          v = value
83
        end
84
        add_default_name_and_id(options)
85
        values = enum_values
86
        raise ArgumentError, "No values for enum select tag" unless values
87
        tag_text = ''
88
        template = options.dup
89
        template.delete('checked')
90
        values.each do |enum|
91
          opts = template.dup
92
          opts['checked'] = 'checked' if v and v == enum
93
          opts['id'] = "#{opts['id']}_#{enum}"
94
          tag_text << "<label>#{enum}: "
95
          tag_text << to_radio_button_tag(enum, opts)
96
          tag_text << "</label>"
97
        end
98
        tag_text
99
      end
100

  
101
      # Gets the list of values for the column.
102
      def enum_values
103
        object.send("column_for_attribute", @method_name).values
104
      end
105
    end
106
  end
107
end
vendor/plugins/enum-column/lib/enum/enum_adapter.rb
1

  
2
# This module provides all the column helper methods to deal with the
3
# values and adds the common type management code for the adapters.
4
module ActiveRecordEnumerations
5
  module Column
6
    # Add the values accessor to the column class.
7
    def self.included(klass)
8
      klass.module_eval <<-EOE
9
        def values; @limit; end
10
      EOE
11
    end
12

  
13
    # Add the type to the native database types. This will most
14
    # likely need to be modified in the adapter as well.
15
    def native_database_types
16
      types = super
17
      types[:enum] = { :name => "enum" }
18
      types
19
    end
20

  
21
    # The new constructor with a values argument.
22
    def initialize(name, default, sql_type = nil, null = true, values = nil)
23
      super(name, default, sql_type, null)
24
      @limit = values if type == :enum
25
    end
26

  
27
    # The class for enum is Symbol.
28
    def klass
29
      if type == :enum
30
        Symbol
31
      else
32
        super
33
      end
34
    end
35

  
36
    # Convert to a symbol.
37
    def type_cast(value)
38
      return nil if value.nil?
39
      if type == :enum
40
        ActiveRecordEnumerations::Column.value_to_symbol(value)
41
      else
42
        super
43
      end
44
    end
45

  
46
    # Code to convert to a symbol.
47
    def type_cast_code(var_name)
48
      if type == :enum
49
        "ActiveRecordEnumerations::Column.value_to_symbol(#{var_name})"
50
      else
51
        super
52
      end
53
    end
54

  
55
    # The enum simple type.
56
    def simplified_type(field_type)
57
      if field_type =~ /enum/i
58
        :enum
59
      else
60
        super
61
      end
62
    end
63

  
64
    # Safely convert the value to a symbol. 
65
    def self.value_to_symbol(value)
66
      case value
67
      when Symbol
68
        value
69
      when String
70
        value.empty? ? nil : value.intern
71
      else
72
        nil
73
      end
74
    end
75
  end
76
end
vendor/plugins/enum-column/lib/enum/mysql_adapter.rb
1

  
2
module ActiveRecord
3
  module ConnectionAdapters
4
    class MysqlAdapter
5
      alias __native_database_types_enum native_database_types
6
      
7
      def native_database_types #:nodoc
8
        types = __native_database_types_enum
9
        types[:enum] = { :name => "enum" }
10
        types
11
      end
12

  
13
      def columns(table_name, name = nil)#:nodoc:
14
        sql = "SHOW FIELDS FROM #{table_name}"
15
        columns = []
16
        execute(sql, name).each { |field| columns << MysqlColumnWithEnum.new(field[0], field[4], field[1], field[2] == "YES") }
17
        columns
18
      end
19
    end
20
    
21
    class MysqlColumnWithEnum < MysqlColumn
22
      include ActiveRecordEnumerations::Column
23
      
24
      def initialize(name, default, sql_type = nil, null = true)
25
        if sql_type =~ /^enum/i
26
          values = sql_type.sub(/^enum\('([^)]+)'\)/i, '\1').split("','").map { |v| v.intern }
27
          default = default.intern if default and !default.empty?
28
        end
29
        super(name, default, sql_type, null, values)
30
      end
31
    end
32
  end
33
end
vendor/plugins/enum-column/lib/enum/postgresql_adapter.rb
1
module ActiveRecord
2
  module ConnectionAdapters
3
    class PostgreSQLAdapter
4
      alias __native_database_types_enum native_database_types
5
      
6
      def native_database_types #:nodoc
7
        types = __native_database_types_enum
8
        types[:enum] = { :name => "character varying(32)" }
9
        types
10
      end
11

  
12
      def columns(table_name, name = nil)#:nodoc:
13
        column_definitions(table_name).collect do |name, type, default, notnull, consrc|
14
          values = nil
15
          if consrc and consrc =~ /ANY \(\(ARRAY(\[[^]]+\])/o and type == native_database_types[:enum][:name]
16
            values = eval $1.gsub(/::character varying/, '')
17
            type = 'enum'
18
          end
19
          
20
          # typmod now unused as limit, precision, scale all handled by superclass
21
          PostgreSQLColumnWithEnum.new(name, default_value(default),
22
                                       translate_field_type(type), notnull == "f",
23
                                       values)
24
        end
25
      end
26

  
27
      # Add constraints to the list of columns. This will only pick up check constraints.
28
      # We'll filter the constraint for the column type and ANY ((ARRAY[ type.
29
      def column_definitions(table_name)
30
        query <<-end_sql
31
          SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull, c.consrc
32
            FROM pg_attribute a LEFT JOIN pg_attrdef d
33
              ON a.attrelid = d.adrelid AND a.attnum = d.adnum
34
              LEFT JOIN pg_constraint c ON a.attrelid = c.conrelid AND 
35
                c.contype = 'c' AND c.conkey[1] = a.attnum
36
            WHERE a.attrelid = '#{table_name}'::regclass
37
              AND a.attnum > 0 AND NOT a.attisdropped
38
            ORDER BY a.attnum
39
        end_sql
40
      end
41

  
42
      def add_column_options!(sql, options)
43
        unless sql =~ /\(32\)\('[^']+'/
44
          super(sql, options)
45
        else
46
          sql.gsub!(/("[^"]+")([^3]+32\))(.+)/, '\1\2 CHECK(\1 in \3)')
47
          super(sql, options)
48
        end
49
      end
50
    end
51
    
52
    class PostgreSQLColumnWithEnum < Column
53
      include ActiveRecordEnumerations::Column
54
      
55
      def initialize(name, default, sql_type = nil, null = true, values = nil)
56
        if values
57
          values = values.map { |v| v.intern }
58
          default = default.intern if default and !default.empty?
59
        end
60
        super(name, default, sql_type, null, values)
61
      end
62
    end
63
  end
64
end
vendor/plugins/enum-column/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
vendor/plugins/enum-column/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
vendor/plugins/enum-column/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
          column_type_sql          
20
        else
21
          # Edge rails fallback for Rails 1.1.6. We can remove the
22
          # rescue once everyone has upgraded to 1.2.
23
          begin
24
            __type_to_sql_enum(type, limit, precision, scale)
25
          rescue ArgumentError
26
            __type_to_sql_enum(type, limit)
27
          end
28
        end
29
      end
30
    end
31
  end
32
end
vendor/plugins/enum-column/lib/enum/sqlite3_adapter.rb
1
module ActiveRecord
2
  module ConnectionAdapters
3
    class SQLite3Adapter
4
      alias __native_database_types_enum native_database_types
5
      
6
      def native_database_types #:nodoc
7
        types = __native_database_types_enum
8
        types[:enum] = { :name => "varchar(32)" }
9
        types
10
      end
11

  
12
      def columns(table_name, name = nil)#:nodoc:
13
        constraints = { }
14
        @connection.execute "SELECT sql FROM sqlite_master WHERE name = '#{table_name}'" do |row|
15
          sql = row[0]
16
          sql.scan(/, \"(\w+)\" varchar\(32\) CHECK\(\"\w+\" in \(([^\)]+)\)/i) do |column, constraint|
17
            constraints[column] = constraint
18
          end
19
        end
20
        table_structure(table_name).map do |field|
21
          name = field['name']
22
          type = field['type']
23
          if (const = constraints[name])
24
            type = "enum(#{const.strip})"
25
          end
26
          SQLite3ColumnWithEnum.new(name, field['dflt_value'], type, field['notnull'] == "0")
27
        end
28
      end
29

  
30
      def add_column_options!(sql, options)
31
        unless sql =~ /\(32\)\('[^']+'/
32
          super(sql, options)
33
        else
34
          sql.gsub!(/("[^"]+")([^3]+32\))(.+)/, '\1\2 CHECK(\1 in \3)')
35
          super(sql, options)
36
        end
37
      end
38
    end
39
    
40
    class SQLite3ColumnWithEnum < SQLiteColumn
41
      include ActiveRecordEnumerations::Column
42
      
43
      def initialize(name, default, sql_type = nil, null = true)
44
        if sql_type =~ /^enum/i
45
          values = sql_type.sub(/^enum\('([^)]+)'\)/i, '\1').split("','").map { |v| v.intern }
46
          default = default.intern if default and !default.empty?
47
        end
48
        super(name, default, sql_type, null, values)
49
      end
50
    end
51
  end
52
end
vendor/plugins/enum-column/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.values, :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
vendor/plugins/enum-column/readme.html
1
<html>
2
<head>
3
<title>Ruby on Rails Enumerated Column Constraints</title>
4
<style>
5
body { 
6
    font-family: "Lucida Sans", Verdana, sans-serif;
7
    font-size: small;
8
}
9

  
10
h1 { font-size: 175%; }
11

  
12
.indent { 
13
    margin-left: 4em;
14
}
15

  
16
</style>
17
</head>
18
<body>
19
  <h1>Ruby on Rails Enumerated Column Constraints</h1>
20
  <h2>Overview</h2>
21
  <p>This plugin is an ROR extension to support enumerations in the database schema using the enum type in MySQL or column constraints in other databases. Currently only MySQL has been implemented, but other connection adapters can easily be extended to check for column constraints and then parse out the possible values.</p>
22

  
23
  <p>This makes it very easy to implement and maintain controlled vocabularies in the database schema without having to change the validations and the view. I have made an effort to make the modifications without modifying the core classes, but I have not been extreamly successful. I have had to make some modifications that are version dependent and then put some exception handlers to make the backward compatible. </p>
24

  
25
<p>This is not the ideal solution and could cause some performance issues in the helpers. The core code still works with both 1.1 and 1.2 without modification.</p>
26

  
27
<h2>Installation</h2>
28

  
29
<p>To install using the plugin script:</p>
30
<pre>
31
    script/plugin install enum-column
32
</pre>
33

  
34
<p>To manually install using Subversion, do the following. In your <code>vendor/plugins</code> directory, 
35
  type the following:<p>
36
<pre>
37
    svn checkout svn://rubyforge.org/var/svn/enum-column
38
</pre>
39

  
40
<p>Otherwize download the latest zip or tarball and unpack it in your <code>vendor/plugins</code> directory.</p>
41

  
42
<h2>How to use it.</h2>
43

  
44
<h3>In your schema</h3>
45

  
46
<p>When you create your schema, specify the constraint as a limit:</p>
47
<pre>
48
  create_table :enumerations, :force => true do |t|
49
    t.column :severity, :enum, :limit =&gt; [:low, :medium, :high, :critical],
50
       :default => :medium
51
    t.column :color, :enum, :limit =&gt; [:red, :blue, :green, :yellow]
52
    ...
53
  end
54
</pre>
55

  
56
<h3>In the model</h3>
57
<p>You can then automatically validate this column using:</p>
58
<pre>
59
    validates_columns :severity, :color
60
</pre>
61

  
62
<p>The rest will be handled for you. All enumerated values will be given as symbols.</p>
63
<pre>
64
    @e = Enumeration.new
65
    @e.severity = :low
66
</pre>
67

  
68
<h3>In the views.</h3>
69

  
70
<p>In the controller:</p>
71
<pre>
72
   @e = Enumeration.new
73
</pre>
74

  
75
<p>The enumerates list of values will be specified as follows:</p>
76
<pre>
77
    &lt;%= input 'e', 'severity' %&gt;
78
</pre>
79

  
80
<p>Will create a select/option list:</p>
81
<pre>
82
     &lt;select id="e_severity" name="e[severity]"&gt;
83
     	     &lt;option value="low"&gt;low&lt;/option&gt;
84
	     &lt;option value="medium" selected="selected"&gt;medium&lt;/option&gt;
85
	     &lt;option value="high"&gt;high&lt;/option&gt;
86
	     &lt;option value="critical"&gt;critical&lt;/option&gt;
87
     &lt;/select&gt;
88
</pre>
89

  
90
<div class="indent">
91
     <select id="e_severity" name="e[severity]">
92
     	     <option value="low">low</option>
93
	     <option value="medium" selected="selected">medium</option>
94
	     <option value="high">high</option>
95
	     <option value="critical">critical</option>
96
     </select>
97
</div>
98

  
99
<p>You can also create a set of radio buttons using the following helper:</p>
100
<pre>
101
    &lt;%= enum_radio('e', 'severity') %=&gt;
102
</pre>
103
<p>Will produce the following group of radio buttons:</p>
104
<pre>
105
    &lt;label&gt;low: &lt;input id="test_severity_low" name="test[severity]" type="radio" value="low" /&gt;&lt;/label&gt;
106
    &lt;label&gt;medium: &lt;input checked="checked" id="test_severity_medium" name="test[severity]" type="radio" value="medium" /&gt;&lt;/label&gt;
107
    &lt;label&gt;high: &lt;input id="test_severity_high" name="test[severity]" type="radio" value="high" /&gt;&lt;/label&gt;
108
    &lt;label&gt;critical: &lt;input id="test_severity_critical" name="test[severity]" type="radio" value="critical" /&gt;&lt;/label&gt;
109
</pre>
110

  
111
<div class="indent">
112
    <label>low: <input id="test_severity_low" name="test[severity]" type="radio" value="low" /></label>
113
    <label>medium: <input checked="checked" id="test_severity_medium" name="test[severity]" type="radio" value="medium" /></label>
114
    <label>high: <input id="test_severity_high" name="test[severity]" type="radio" value="high" /></label>
115
    <label>critical: <input id="test_severity_critical" name="test[severity]" type="radio" value="critical" /></label>
116
</div>
117

  
118
<p>You can always use the column reflection to get the list of possible values from the database column. </p>
119
<pre>
120
    Enumeration.columns_hash['color'].values
121
    
122
    Will yield: [:red, :blue, :green, :yellow]
123
</pre>
124

  
125

  
vendor/plugins/enum-column/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
vendor/plugins/enum-column/test/enum_mysql_test.rb
1
require File.dirname(__FILE__) + '/test_helper'
2
require 'fixtures/enumeration'
3

  
4
class EnumerationsTest < Test::Unit::TestCase
5
  class EnumController < ActionController::Base
6
    def test1
7
      @test = Enumeration.new
8
      render :inline => "<%= input('test', 'severity')%>"
9
    end
10

  
11
    def test2
12
      @test = Enumeration.new
13
      render :inline => "<%= enum_radio('test', 'severity')%>"
14
    end
15
  end
16

  
17
  def setup
18
    Enumeration.connection.execute 'DELETE FROM enumerations'
19
  end
20
  
21
  def test_column_values
22
    columns = Enumeration.columns_hash
23
    color_column = columns['color']
24
    assert color_column
25
    assert_equal [:red, :blue, :green, :yellow], color_column.values
26

  
27
    severity_column = columns['severity']
28
    assert severity_column
29
    assert_equal [:low, :medium, :high, :critical], severity_column.values
30
    assert_equal :medium, severity_column.default
31
  end
32

  
33
  def test_insert_enum
34
    row = Enumeration.new
35
    row.color = :blue
36
    row.string_field = 'test'
37
    assert_equal :medium, row.severity
38
    assert row.save
39

  
40
    db_row = Enumeration.find(row.id)
41
    assert db_row
42
    assert :blue, row.color
43
    assert :medium, row.severity
44
  end
45

  
46
  # Uses the automatic validates_columns to create automatic validation rules
47
  # for columns based on the schema information.
48
  def test_bad_value
49
    row = Enumeration.new
50
    row.color = :violet
51
    row.string_field = 'test'
52
    assert !row.save
53
    
54
    assert row.errors
55
    assert_equal 'is not included in the list', row.errors['color']
56
  end
57

  
58
  def test_other_types
59
    row = Enumeration.new
60
    row.string_field = 'a' * 10
61
    assert !row.save
62
    assert_equal 'is too long (maximum is 8 characters)', row.errors['string_field']
63

  
64
    row = Enumeration.new
65
    assert !row.save
66
    assert_equal 'can\'t be blank', row.errors['string_field']
67

  
68
    row = Enumeration.new
69
    row.string_field = 'test'
70
    row.int_field = 'aaaa'
71
    assert !row.save
72
    assert_equal 'is not a number', row.errors['int_field']
73

  
74
    row = Enumeration.new
75
    row.string_field = 'test'
76
    row.int_field = '500'
77
    assert row.save
78
  end
79

  
80
  def test_view_helper
81
    request  = ActionController::TestRequest.new
82
    response = ActionController::TestResponse.new
83
    request.action = 'test1'
84
    body = EnumController.process(request, response).body
85
    assert_equal '<select id="test_severity" name="test[severity]"><option value="low">low</option><option value="medium" selected="selected">medium</option><option value="high">high</option><option value="critical">critical</option></select>', body
86
  end
87

  
88
  def test_radio_helper
89
    request  = ActionController::TestRequest.new
90
    response = ActionController::TestResponse.new
91
    request.action = 'test2'
92
    body = EnumController.process(request, response).body
93
    assert_equal '<label>low: <input id="test_severity_low" name="test[severity]" type="radio" value="low" /></label><label>medium: <input checked="checked" id="test_severity_medium" name="test[severity]" type="radio" value="medium" /></label><label>high: <input id="test_severity_high" name="test[severity]" type="radio" value="high" /></label><label>critical: <input id="test_severity_critical" name="test[severity]" type="radio" value="critical" /></label>', body
94
  end
95

  
96

  
97
  # Basic tests
98
  def test_create_basic_default
99
    assert (object = BasicEnum.create)
100
    assert_nil object.value,
101
      "Enum columns without explicit default, default to null if allowed"
102
    assert !object.new_record?
103
  end
104

  
105
  def test_create_basic_good
106
    assert (object = BasicEnum.create(:value => :good))
107
    assert_equal :good, object.value
108
    assert !object.new_record?
109
    assert (object = BasicEnum.create(:value => :working))
110
    assert_equal :working, object.value
111
    assert !object.new_record?
112
  end
113

  
114
  def test_create_basic_null
115
    assert (object = BasicEnum.create(:value => nil))
116
    assert_nil object.value
117
    assert !object.new_record?
118
  end
119

  
120
  def test_create_basic_bad
121
    assert (object = BasicEnum.create(:value => :bad))
122
    assert object.new_record?
123
  end
124

  
125
  # Basic w/ Default
126

  
127
  ######################################################################
128

  
129
  def test_create_basic_wd_default
130
    assert (object = BasicDefaultEnum.create)
131
    assert_equal :working, object.value, "Explicit default ignored columns"
132
    assert !object.new_record?
133
  end
134

  
135
  def test_create_basic_wd_good
136
    assert (object = BasicDefaultEnum.create(:value => :good))
137
    assert_equal :good, object.value
138
    assert !object.new_record?
139
    assert (object = BasicDefaultEnum.create(:value => :working))
140
    assert_equal :working, object.value
141
    assert !object.new_record?
142
  end
143

  
144
  def test_create_basic_wd_null
145
    assert (object = BasicDefaultEnum.create(:value => nil))
146
    assert_nil object.value
147
    assert !object.new_record?
148
  end
149

  
150
  def test_create_basic_wd_bad
151
    assert (object = BasicDefaultEnum.create(:value => :bad))
152
    assert object.new_record?
153
  end
154

  
155

  
156

  
157
  # Nonnull
158

  
159
  ######################################################################
160

  
161
  def test_create_nonnull_default
162
    assert (object = NonnullEnum.create)
163
#    assert_equal :good, object.value,
164
#      "Enum columns without explicit default, default to first value if null not allowed"
165
    assert object.new_record?
166
  end
167

  
168
  def test_create_nonnull_good
169
    assert (object = NonnullEnum.create(:value => :good))
170
    assert_equal :good, object.value
171
    assert !object.new_record?
172
    assert (object = NonnullEnum.create(:value => :working))
173
    assert_equal :working, object.value
174
    assert !object.new_record?
175
  end
176

  
177
  def test_create_nonnull_null
178
    assert (object = NonnullEnum.create(:value => nil))
179
    assert object.new_record?
180
  end
181

  
182
  def test_create_nonnull_bad
183
    assert (object = NonnullEnum.create(:value => :bad))
184
    assert object.new_record?
185
  end
186

  
187
  # Nonnull w/ Default
188

  
189
  ######################################################################
190

  
191
  def test_create_nonnull_wd_default
192
    assert (object = NonnullDefaultEnum.create)
193
    assert_equal :working, object.value
194
    assert !object.new_record?
195
  end
196

  
197
  def test_create_nonnull_wd_good
198
    assert (object = NonnullDefaultEnum.create(:value => :good))
199
    assert_equal :good, object.value
200
    assert !object.new_record?
201
    assert (object = NonnullDefaultEnum.create(:value => :working))
202
    assert_equal :working, object.value
203
    assert !object.new_record?
204
  end
205

  
206
  def test_create_nonnull_wd_null
207
    assert (object = NonnullDefaultEnum.create(:value => nil))
208
    assert object.new_record?
209
  end
210

  
211
  def test_create_nonnull_wd_bad
212
    assert (object = NonnullDefaultEnum.create(:value => :bad))
213
    assert object.new_record?
214
  end
215

  
216
  def test_quoting
217
    value = ActiveRecord::Base.send(:sanitize_sql, ["value = ? ", :"'" ] )
218
    assert_equal "value = '\\'' ", value
219
  end
220
end
vendor/plugins/enum-column/test/fixtures/db_definitions/mysql.drop.sql
1
DROP TABLE accounts;
2
DROP TABLE funny_jokes;
3
DROP TABLE companies;
4
DROP TABLE topics;
5
DROP TABLE developers;
6
DROP TABLE projects;
7
DROP TABLE developers_projects;
8
DROP TABLE customers;
9
DROP TABLE orders;
10
DROP TABLE movies;
11
DROP TABLE subscribers;
12
DROP TABLE booleantests;
13
DROP TABLE auto_id_tests;
14
DROP TABLE entrants;
15
DROP TABLE colnametests;
16
DROP TABLE mixins;
17
DROP TABLE people;
18
DROP TABLE readers;
19
DROP TABLE binaries;
20
DROP TABLE computers;
21
DROP TABLE tasks;
22
DROP TABLE posts;
23
DROP TABLE comments;
24
DROP TABLE authors;
25
DROP TABLE categories;
26
DROP TABLE categories_posts;
27
DROP TABLE fk_test_has_fk;
28
DROP TABLE fk_test_has_pk;
29
DROP TABLE keyboards;
30
DROP TABLE enumerations;
31
DROP TABLE legacy_things;
32
DROP TABLE numeric_data;
vendor/plugins/enum-column/test/fixtures/db_definitions/mysql.sql
1
CREATE TABLE `accounts` (
2
  `id` int(11) NOT NULL auto_increment,
3
  `firm_id` int(11) default NULL,
4
  `credit_limit` int(5) default NULL,
5
  PRIMARY KEY  (`id`)
6
) TYPE=InnoDB;
7

  
8
CREATE TABLE `funny_jokes` (
9
  `id` int(11) NOT NULL auto_increment,
10
  `name` varchar(50) default NULL,
11
  PRIMARY KEY  (`id`)
12
) TYPE=InnoDB;
13

  
14
CREATE TABLE `companies` (
15
  `id` int(11) NOT NULL auto_increment,
16
  `type` varchar(50) default NULL,
17
  `ruby_type` varchar(50) default NULL,
18
  `firm_id` int(11) default NULL,
19
  `name` varchar(50) default NULL,
20
  `client_of` int(11) default NULL,
21
  `rating` int(11) default NULL default 1,
22
  PRIMARY KEY  (`id`)
23
) TYPE=InnoDB;
24

  
25

  
26
CREATE TABLE `topics` (
27
  `id` int(11) NOT NULL auto_increment,
28
  `title` varchar(255) default NULL,
29
  `author_name` varchar(255) default NULL,
30
  `author_email_address` varchar(255) default NULL,
31
  `written_on` datetime default NULL,
32
  `bonus_time` time default NULL,
33
  `last_read` date default NULL,
34
  `content` text,
35
  `approved` tinyint(1) default 1,
36
  `replies_count` int(11) default 0,
37
  `parent_id` int(11) default NULL,
38
  `type` varchar(50) default NULL,
39
  PRIMARY KEY  (`id`)
40
) TYPE=InnoDB;
41

  
42
CREATE TABLE `developers` (
43
  `id` int(11) NOT NULL auto_increment,
44
  `name` varchar(100) default NULL,
45
  `salary` int(11) default 70000,
46
  `created_at` datetime default NULL,
47
  `updated_at` datetime default NULL,
48
  PRIMARY KEY  (`id`)
49
) TYPE=InnoDB;
50

  
51
CREATE TABLE `projects` (
52
  `id` int(11) NOT NULL auto_increment,
53
  `name` varchar(100) default NULL,
54
  `type` VARCHAR(255) default NULL,
55
  PRIMARY KEY  (`id`)
56
) TYPE=InnoDB;
57

  
58
CREATE TABLE `developers_projects` (
59
  `developer_id` int(11) NOT NULL,
60
  `project_id` int(11) NOT NULL,
61
  `joined_on` date default NULL,
62
  `access_level` smallint default 1
63
) TYPE=InnoDB;
64

  
65
CREATE TABLE `orders` (
66
  `id` int(11) NOT NULL auto_increment,
67
  `name` varchar(100) default NULL,
68
  `billing_customer_id` int(11) default NULL,
69
  `shipping_customer_id` int(11) default NULL,
70
  PRIMARY KEY  (`id`)
71
) TYPE=InnoDB;
72

  
73
CREATE TABLE `customers` (
74
  `id` int(11) NOT NULL auto_increment,
75
  `name` varchar(100) default NULL,
76
  `balance` int(6) default 0,
77
  `address_street` varchar(100) default NULL,
78
  `address_city` varchar(100) default NULL,
79
  `address_country` varchar(100) default NULL,
80
  `gps_location` varchar(100) default NULL,
81
  PRIMARY KEY  (`id`)
82
) TYPE=InnoDB;
83

  
84
CREATE TABLE `movies` (
85
  `movieid` int(11) NOT NULL auto_increment,
86
  `name` varchar(100) default NULL,
87
   PRIMARY KEY  (`movieid`)
88
) TYPE=InnoDB;
89

  
90
CREATE TABLE `subscribers` (
91
  `nick` varchar(100) NOT NULL,
92
  `name` varchar(100) default NULL,
93
  PRIMARY KEY  (`nick`)
94
) TYPE=InnoDB;
95

  
96
CREATE TABLE `booleantests` (
97
  `id` int(11) NOT NULL auto_increment,
98
  `value` integer default NULL,
99
  PRIMARY KEY (`id`)
100
) TYPE=InnoDB;
101

  
102
CREATE TABLE `auto_id_tests` (
103
  `auto_id` int(11) NOT NULL auto_increment,
104
  `value` integer default NULL,
105
  PRIMARY KEY (`auto_id`)
106
) TYPE=InnoDB;
107

  
108
CREATE TABLE `entrants` (
109
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
110
  `name` VARCHAR(255) NOT NULL,
111
  `course_id` INTEGER NOT NULL
112
);
113

  
114
CREATE TABLE `colnametests` (
115
  `id` int(11) NOT NULL auto_increment,
116
  `references` int(11) NOT NULL,
117
  PRIMARY KEY (`id`)
118
) TYPE=InnoDB;
119

  
120
CREATE TABLE `mixins` (
121
  `id` int(11) NOT NULL auto_increment,
122
  `parent_id` int(11) default NULL,
123
  `pos` int(11) default NULL,
124
  `created_at` datetime default NULL,
125
  `updated_at` datetime default NULL,
126
  `lft` int(11) default NULL,
127
  `rgt` int(11) default NULL,
128
  `root_id` int(11) default NULL,
129
  `type` varchar(40) default NULL,
130
  PRIMARY KEY  (`id`)
131
) TYPE=InnoDB;
132

  
133
CREATE TABLE `people` (
134
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
135
  `first_name` VARCHAR(40) NOT NULL,
136
  `lock_version` INTEGER NOT NULL DEFAULT 0
137
) TYPE=InnoDB;
138

  
139
CREATE TABLE `readers` (
140
    `id` int(11) NOT NULL auto_increment PRIMARY KEY,
141
    `post_id` INTEGER NOT NULL,
142
    `person_id` INTEGER NOT NULL
143
) TYPE=InnoDB;
144

  
145
CREATE TABLE `binaries` (
146
  `id` int(11) NOT NULL auto_increment,
147
  `data` mediumblob,
148
  PRIMARY KEY  (`id`)
149
) TYPE=InnoDB;
150

  
151
CREATE TABLE `computers` (
152
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
153
  `developer` INTEGER NOT NULL,
154
  `extendedWarranty` INTEGER NOT NULL
155
) TYPE=InnoDB;
156

  
157
CREATE TABLE `posts` (
158
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
159
  `author_id` INTEGER,
160
  `title` VARCHAR(255) NOT NULL,
161
  `body` TEXT NOT NULL,
162
  `type` VARCHAR(255) NOT NULL
163
) TYPE=InnoDB;
164

  
165
CREATE TABLE `comments` (
166
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
167
  `post_id` INTEGER NOT NULL,
168
  `body` TEXT NOT NULL,
169
  `type` VARCHAR(255) NOT NULL
170
) TYPE=InnoDB;
171

  
172
CREATE TABLE `authors` (
173
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
174
  `name` VARCHAR(255) NOT NULL
175
) TYPE=InnoDB;
176

  
177
CREATE TABLE `tasks` (
178
  `id` int(11) NOT NULL auto_increment,
179
  `starting` datetime NOT NULL default '0000-00-00 00:00:00',
180
  `ending` datetime NOT NULL default '0000-00-00 00:00:00',
181
  PRIMARY KEY  (`id`)
182
) TYPE=InnoDB;
183

  
184
CREATE TABLE `categories` (
185
  `id` int(11) NOT NULL auto_increment,
186
  `name` VARCHAR(255) NOT NULL,
187
  `type` VARCHAR(255) NOT NULL,
188
  PRIMARY KEY  (`id`)
189
) TYPE=InnoDB;
190

  
191
CREATE TABLE `categories_posts` (
192
  `category_id` int(11) NOT NULL,
193
  `post_id` int(11) NOT NULL
194
) TYPE=InnoDB;
195

  
196
CREATE TABLE `fk_test_has_pk` (
197
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY
198
) TYPE=InnoDB;
199

  
200
CREATE TABLE `fk_test_has_fk` (
201
  `id`    INTEGER NOT NULL auto_increment PRIMARY KEY,
202
  `fk_id` INTEGER NOT NULL,
203

  
204
  FOREIGN KEY (`fk_id`) REFERENCES `fk_test_has_pk`(`id`)
205
) TYPE=InnoDB;
206

  
207

  
208
CREATE TABLE `keyboards` (
209
  `key_number` int(11) NOT NULL auto_increment primary key,
210
  `name` varchar(50) default NULL
211
);
212

  
213
<<<<<<< .mine
214
CREATE TABLE `enumerations` (
215
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
216
  `severity` enum('low', 'medium', 'high', 'critical') DEFAULT 'medium',
217
  `color`    enum('red', 'blue', 'green', 'yellow'),
218
  `string_field` varchar(8) NOT NULL,
219
  `int_field`    int(11)
220
) TYPE=InnoDB;
221

  
222
--Altered lock_version column name.
223
=======
224
-- Altered lock_version column name.
225
>>>>>>> .r3595
226
CREATE TABLE `legacy_things` (
227
  `id` int(11) NOT NULL auto_increment,
228
  `tps_report_number` int(11) default NULL,
229
  `version` int(11) NOT NULL default 0,
230
  PRIMARY KEY  (`id`)
231
) TYPE=InnoDB;
232
<<<<<<< .mine
233

  
234
=======
235

  
236
CREATE TABLE `numeric_data` (
237
  `id` INTEGER NOT NULL auto_increment PRIMARY KEY,
238
  `bank_balance` decimal(10,2),
239
  `big_bank_balance` decimal(15,2),
240
  `world_population` decimal(10),
241
  `my_house_population` decimal(2),
242
  `decimal_number_with_default` decimal(3,2) DEFAULT 2.78
243
) TYPE=InnoDB;
244
>>>>>>> .r4885
vendor/plugins/enum-column/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
vendor/plugins/enum-column/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
Test::Unit::TestCase.fixture_path = fixture_path
14
$LOAD_PATH.unshift(Test::Unit::TestCase.fixture_path)
15
$LOAD_PATH.unshift(File.dirname(__FILE__))
16
# =============================================================================
17

  
18

  
(1-1/7)