There are already tickets supposed to tackle autovalidation like the
one you have proposed and more. Please see #608 and #1112. They are
different in approach but have, the common goal to extract as much
validation as possible from database schema. Also adapters other than
postgresql or mysql are not implemented.
#608 uses has autovalidation enabled by default (numerocality_of ,for
not null, length_of etc). Also option to disable at global level as
well as individual column level is also provided. Works only with
Mysql.
While #1112 works with postgress too and does validates_uniqueness_of
also. Autovalidation is off by default.
If we would like to see this feature we should make an unification,
that means taking the best from each and make it great:
In my opinion it should be:
* fully automatic without having to write special macros( except for
disabling of course)
* cover all possible validations. Perhaps providing an option to
selectively disable expensive ones like validates_uniqueness_of
* above all should be simple for the developer to use
Zsombor
On 5/17/05, Michael Schuerig
<michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org>
wrote:>
> I''ve hacked together a couple of changes for adding
> validates_presence_of validations based on NOT NULL constraints in the
> database. Currently it only works with PostgreSQL, but if the necessary
> information can be obtained from the other DBMSs, then there''s no
> problem with doing the same there.
>
> This database-based validation is enabled with the new class method
>
> validates_presence_of_not_null_columns
>
> A further addition is that input fields for mandatory ("not
null")
> attributes when inserted by helper methods get the additional class
> ''mandatory''.
>
> See the code below. I''m looking forward to your comments.
>
> Michael
>
> PostgreSQL Adapter: In addition to what was already present, retrieve
> the is_nullable property.
>
> require
''active_record/connection_adapters/abstract_adapter''
> require ''parsedate''
>
> module ActiveRecord
>
> module ConnectionAdapters
> class PostgreSQLAdapter < AbstractAdapter
> def columns(table_name, name = nil)
> table_structure(table_name).inject([]) do |columns, field|
> columns << Column.new(field[0], field[2], field[1],
field[4])
> columns
> end
> end
>
> private
>
> def table_structure(table_name)
> database_name = @connection.db
> schema_name, table_name = split_table_schema(table_name)
>
> # Grab a list of all the default values for the columns.
> sql = "SELECT column_name, column_default,
> character_maximum_length, data_type, is_nullable " ### ! ###
> sql << " FROM information_schema.columns "
> sql << " WHERE table_catalog =
''#{database_name}'' "
> sql << " AND table_schema =
''#{schema_name}'' "
> sql << " AND table_name =
''#{table_name}'';"
>
> column_defaults = nil
> log(sql, nil, @connection) { |connection| column_defaults >
connection.query(sql) }
> column_defaults.collect do |row|
> field = row[0]
> type = type_as_string(row[3], row[2])
> default = default_value(row[1])
> length = row[2]
> is_nullable = (row[4] == ''YES'')
>
> [field, type, default, length, is_nullable]
> end
> end
> end
> end
> end
>
> Column class: add an is_nullable attribute.
>
> module ActiveRecord
> module ConnectionAdapters # :nodoc:
> class Column # :nodoc:
> attr_reader :name, :default, :type, :limit, :is_nullable ### ! ###
>
> def initialize(name, default, sql_type, is_nullable)
> @name, @default, @type, @is_nullable = name, default,
> simplified_type(sql_type), is_nullable ### ! ###
> @limit = extract_limit(sql_type) unless sql_type.nil?
> end
> end
>
> end
> end
>
> ActiveRecord: add validation method
> validates_presence_of_not_null_columns and utility method
> mandatory_columns.
>
> module ActiveRecord
> module Validations
> module ClassMethods
>
> def validates_presence_of_not_null_columns
> validates_presence_of(*mandatory_columns)
> end
>
> def is_mandatory_column?(column_name)
> mandatory_columns.include?(column_name)
> end
>
> private
>
> def mandatory_columns
> columns.find_all { |col| !col.is_nullable }.map do |col|
> col.name
> end
> end
>
> end
> end
> end
>
> InstanceTag: Add ''mandatory'' to class of elements whose
corresponding
> attribute may not be null.
>
> module ActionView
> module Helpers
> class InstanceTag
>
> alias_method :to_input_field_tag_without_mandatory,
> :to_input_field_tag
> def to_input_field_tag(field_type, options = {})
> if field_type != ''hidden'' and is_mandatory
> to_input_field_tag_without_mandatory(field_type,
> add_class(options, ''mandatory''))
> else
> to_input_field_tag_without_mandatory(field_type, options)
> end
> end
>
> private
>
> def is_mandatory
> object.class.is_mandatory_column?(@method_name)
> end
>
> def add_class(options, className)
> classNames = options[:class]
> if classNames and !classNames.empty?
> classNames += '' '' + className unless
classNames.include?
> (className)
> else
> classNames = className
> end
> options[:class] = classNames
> options
> end
> end
> end
> end
>
> --
> Michael Schuerig You can twist perceptions
> mailto:michael-q5aiKMLteq4b1SvskN2V4Q@public.gmane.org
Reality won''t budge
> http://www.schuerig.de/michael/ --Rush, Show Don''t
Tell
> _______________________________________________
> Rails mailing list
> Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org
> http://lists.rubyonrails.org/mailman/listinfo/rails
>
--
http://deezsombor.blogspot.com