Q: ActiveForm?


#1

This question pops in and out of the mailing list and I’m wondering
whether
others have solved it. Consider the case where the user is filling out a
form but there is no underlying database record (say the contents of the
form are emailed someplace then discarded).

It would be great to use:

<%= text_field(:my_fine_form, ‘last_name’) %>

<%= text_field(:my_fine_form, ‘first_name’) %>

etc.

Then have params[:my_fine_form] automagically populate some object just
as
it does the model. E.g.,

@my_fine_data = MyFineForm.find() # populates from
params[:my_fine_form]
redirect_to :action => ‘entry_form’ unless @my_fine_data.valid?

And even cooler, a form model:

def MyFineForm < ActiveForm
:validates_presence_of :last_name
:persists_in_session => true;

and blah, blah, blah

end

I’d write this myself – I may even have to – but I wanted to make sure
nobody else already has.

Thanks


#2

Steve R. wrote:

:validates_presence_of :last_name
:persists_in_session => true;

and blah, blah, blah

end

I’d write this myself – I may even have to – but I wanted to make sure
nobody else already has.

Well, my hacky way of doing this was just to leverage the entire
ActiveRecord
class, but use a memory based sqlite table that represents the fields in
the
form I want. In the model class itself, I set up the table structure to
represent the fields I want filled out. There’s nothing stored in a
permanent
database. One could even override save and create to throw exceptions
in case
anybody does try to save anything to the db.

ActiveForm could derive from ActiveRecord::Base and use a memory backed
sqlite
database as a backend for ActiveRecord to inflect off of.

Here’s the code:

There are no records that are stored in a database for the model, so

build a memory based Sqlite database to build a schema to help build

an ActiveRecord.

Because no objects instances of this model are stored in the

database, conventional usage of an object of this model is to have

the object’s id be the same as the output type’s id so linking them

up is easy.

class Post < ActiveRecord::Base

unless const_defined? :SQLITE_SETUP
SQLITE_SETUP = true
self.establish_connection(:adapter => ‘sqlite’, :database =>
‘:memory:’)
conn = self.connection
conn.create_table(self.table_name,
:primary_key => self.primary_key) do |t|
t.column :count, :integer
end
end

attr_accessible :count
validates_presence_of :count
validates_numericality_of :count, :only_integer => true
end

Regards,
Blair


#3

Great solution. Just a couple notes:

  1. Not everyone has sqlite. Notably, most Win32 installs don’t.
    Fortunately,
    that’s not where I’m developing or where I’m targeting, to I’m ok.

  2. self.establish_connection(:adapter => ‘sqlite’, :database =>
    ‘:memory:’)
    – should read –
    self.establish_connection(:adapter => ‘sqlite’, :dbfile =>
    ‘:memory:’)

Steve


#4

Steve R. wrote:

Great solution. Just a couple notes:

  1. Not everyone has sqlite. Notably, most Win32 installs don’t. Fortunately,
    that’s not where I’m developing or where I’m targeting, to I’m ok.

That’s good!

  1. self.establish_connection(:adapter => ‘sqlite’, :database => ‘:memory:’)
    – should read –
    self.establish_connection(:adapter => ‘sqlite’, :dbfile => ‘:memory:’)

Actually not. In a recent RoR release, this was changed:

http://dev.rubyonrails.com/changeset/2825

Regards,
Blair