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