Search code examples
ruby-on-railsactiverecordform-helpers

Rails input text maxlength from ActiveRecord limit


I our Rails app, we'd like to prevent a user from physically entering more characters in a text field than can be recorded in the corresponding database field. This seems much friendlier than letting him/her type too much and then be told to try again after the fact.

In other words, all View input text fields should have a maxlength= attribute set equal to the :limit of the corresponding ActiveRecord Model varchar() field.

Is there a way to cause this to happen automatically?

If not, is there a DRY idiom, helper function, or metaprogramming hack that will make it so?


Solution

  • Something like the following (untested) monkey patch might help

    module ActionView
      module Helpers
    
        old_text_field = instance_method(:text_field)                                                           # store a reference to the original text_field method
    
        define_method(:text_field) do |object_name, method, options = {}|                                       # completely redefine the text_field method
          klass     = InstanceTag.new(object_name, method, self, options.delete(:object)).retrieve_object.class # get the class for the object bound to the field
          column    = klass.columns.reject { |c| c.name != method.to_s }.first if klass.present?                # get the column from the class
          maxlength = column.limit if defined?(column) && column.respond_to?(:limit)                            # set the maxlength to the limit for the column if it exists
    
          options.reverse_merge!( maxlength: maxlength ) if defined?(maxlength)                                 # merge the maxlength option in with the rest
    
          old_text_field.bind(self).(object_name, method, options)                                              # pass it up to the original text_field method
        end
      end
    end