Pat Maddox
2006-Jan-19 07:16 UTC
[Rails] Easy way to handle form input without a model class?
I have a couple forms that I''d like to be able to validate and automatically populate, but it shouldn''t be based on AR. In fact I often have a bunch of small forms that I can''t really justify writing a whole new model class for anyway. I''d like to validate the form input, and then use rails helpers to automatically populate the form if validations fail. I''ve already found some links on validating without subclassing from AR, but nothing about auto populating forms without a model, with or without rails helpers. If there''s no existing way to do this, I already have an idea for something simple. I''d write a class that takes a hash at initialization to populate instance variables and automatically add accessors, and use method_missing to handle the object before it''s initialized with the hash. Pretty easy..but I just wanted to see if something like this exists already. Thanks, Pat
Pat Maddox
2006-Jan-19 07:59 UTC
[Rails] Re: Easy way to handle form input without a model class?
Alright here''s what I came up with. It''s a modification of Peter Donald''s ActiveForm (http://www.realityforge.org/articles/2005/12/02/validations-for-non-activerecord-model-objects). The only real differences here are the initialize method, which sets the attributes, and the method_missing, which returns the value of instance_variable_get (which is nil if the instance variable doesn''t exist). Because it returns nil, the form helpers don''t complain about a method not existing. Hopefully some people can take a look at this and improve it a bit. I don''t really like how I''ve had to reimplement method_missing..it does the same exact thing as #[](key). Also some of the stuff in method_missing may be extraneous - I just hacked up a quick thing that works for me. I appreciate any comments, and big thanks to Peter Donald for coming up with the original ActiveForm. # Note ".valid?" method must occur on object for validates_associated class ActiveForm def initialize(init_values = {}) init_values.each{ |key, value| instance_variable_set("@#{key}", value) } end def [](key) instance_variable_get("@#{key}") end def method_missing( method_id, *args ) if md = /_before_type_cast$/.match(method_id.to_s) attr_name = md.pre_match return self[attr_name] if self.respond_to?(attr_name) end instance_variable_get("@#{method_id.to_s}") #super end protected def raise_not_implemented_error(*params) ValidatingModel.raise_not_implemented_error(*params) end def self.human_attribute_name(attribute_key_name) attribute_key_name.humanize end def new_record? true end # these methods must be defined before include alias save raise_not_implemented_error alias update_attribute raise_not_implemented_error public include ActiveRecord::Validations protected # the following methods must be defined after include so that they overide # methods previously included alias save! raise_not_implemented_error class << self def raise_not_implemented_error(*params) raise NotImplementedError end alias validates_uniqueness_of raise_not_implemented_error alias create! raise_not_implemented_error alias validate_on_create raise_not_implemented_error alias validate_on_update raise_not_implemented_error alias save_with_validation raise_not_implemented_error end end require ''dispatcher'' class Dispatcher class << self if ! method_defined?(:form_original_reset_application!) alias :form_original_reset_application! :reset_application! def reset_application! form_original_reset_application! Dependencies.remove_subclasses_for(ActiveForm) if defined?(ActiveForm) end end end end On 1/19/06, Pat Maddox <pergesu@gmail.com> wrote:> I have a couple forms that I''d like to be able to validate and > automatically populate, but it shouldn''t be based on AR. In fact I > often have a bunch of small forms that I can''t really justify writing > a whole new model class for anyway. I''d like to validate the form > input, and then use rails helpers to automatically populate the form > if validations fail. I''ve already found some links on validating > without subclassing from AR, but nothing about auto populating forms > without a model, with or without rails helpers. > > If there''s no existing way to do this, I already have an idea for > something simple. I''d write a class that takes a hash at > initialization to populate instance variables and automatically add > accessors, and use method_missing to handle the object before it''s > initialized with the hash. Pretty easy..but I just wanted to see if > something like this exists already. > > Thanks, > Pat >
Hogan, Brian P.
2006-Jan-19 14:23 UTC
[Rails] Re: Easy way to handle form input without a model class?
See this page: http://rails.techno-weenie.net/tip/2005/11/19/validate_your_forms_with_a _table_less_model It''s awesome and if you know how to tweak it, you can make it do some other cool things as well. -----Original Message----- From: rails-bounces@lists.rubyonrails.org [mailto:rails-bounces@lists.rubyonrails.org] On Behalf Of Pat Maddox Sent: Thursday, January 19, 2006 1:59 AM To: rails@lists.rubyonrails.org Subject: [Rails] Re: Easy way to handle form input without a model class? Alright here''s what I came up with. It''s a modification of Peter Donald''s ActiveForm (http://www.realityforge.org/articles/2005/12/02/validations-for-non-act iverecord-model-objects). The only real differences here are the initialize method, which sets the attributes, and the method_missing, which returns the value of instance_variable_get (which is nil if the instance variable doesn''t exist). Because it returns nil, the form helpers don''t complain about a method not existing. Hopefully some people can take a look at this and improve it a bit. I don''t really like how I''ve had to reimplement method_missing..it does the same exact thing as #[](key). Also some of the stuff in method_missing may be extraneous - I just hacked up a quick thing that works for me. I appreciate any comments, and big thanks to Peter Donald for coming up with the original ActiveForm. # Note ".valid?" method must occur on object for validates_associated class ActiveForm def initialize(init_values = {}) init_values.each{ |key, value| instance_variable_set("@#{key}", value) } end def [](key) instance_variable_get("@#{key}") end def method_missing( method_id, *args ) if md = /_before_type_cast$/.match(method_id.to_s) attr_name = md.pre_match return self[attr_name] if self.respond_to?(attr_name) end instance_variable_get("@#{method_id.to_s}") #super end protected def raise_not_implemented_error(*params) ValidatingModel.raise_not_implemented_error(*params) end def self.human_attribute_name(attribute_key_name) attribute_key_name.humanize end def new_record? true end # these methods must be defined before include alias save raise_not_implemented_error alias update_attribute raise_not_implemented_error public include ActiveRecord::Validations protected # the following methods must be defined after include so that they overide # methods previously included alias save! raise_not_implemented_error class << self def raise_not_implemented_error(*params) raise NotImplementedError end alias validates_uniqueness_of raise_not_implemented_error alias create! raise_not_implemented_error alias validate_on_create raise_not_implemented_error alias validate_on_update raise_not_implemented_error alias save_with_validation raise_not_implemented_error end end require ''dispatcher'' class Dispatcher class << self if ! method_defined?(:form_original_reset_application!) alias :form_original_reset_application! :reset_application! def reset_application! form_original_reset_application! Dependencies.remove_subclasses_for(ActiveForm) if defined?(ActiveForm) end end end end On 1/19/06, Pat Maddox <pergesu@gmail.com> wrote:> I have a couple forms that I''d like to be able to validate and > automatically populate, but it shouldn''t be based on AR. In fact I > often have a bunch of small forms that I can''t really justify writing > a whole new model class for anyway. I''d like to validate the form > input, and then use rails helpers to automatically populate the form > if validations fail. I''ve already found some links on validating > without subclassing from AR, but nothing about auto populating forms > without a model, with or without rails helpers. > > If there''s no existing way to do this, I already have an idea for > something simple. I''d write a class that takes a hash at > initialization to populate instance variables and automatically add > accessors, and use method_missing to handle the object before it''s > initialized with the hash. Pretty easy..but I just wanted to see if > something like this exists already. > > Thanks, > Pat >_______________________________________________ Rails mailing list Rails@lists.rubyonrails.org http://lists.rubyonrails.org/mailman/listinfo/rails