Reusing Forms

2 views
Skip to first unread message

Scott LaBounty

unread,
Jul 2, 2009, 9:53:38 AM7/2/09
to ram...@googlegroups.com
What's the easiest way to reuse a form in a different context? For example if I want to use a form for entering some information and then reuse the same form with the information filled in for editing.

--
Scott
http://steamcode.blogspot.com/

Phrogz

unread,
Jul 2, 2009, 12:27:14 PM7/2/09
to Ramaze
On Jul 2, 7:53 am, Scott LaBounty <slabou...@gmail.com> wrote:
> What's the easiest way to reuse a form in a different context? For example
> if I want to use a form for entering some information and then reuse the
> same form with the information filled in for editing.

Here's what I do (untested simplified version) using Sequel for my
model:

# controller.rb
def new
@item_to_edit = MyItem.new do |item|
item.id = -1
item.some_field = "user-changeable default value"
end
render_partial( :_edit_item, :item=>@item, :action=>:new )
end

def edit( item_id )
@item = MyItem[ item_id ]
render_partial( :_edit_item, :item=>@item, :action=>:edit )
end

def update_item
@item = MyItem[ request['item_id'] ]
unless @item
Ramaze::Log.debug( 'Creating new item!' )
@item = MyItem.new do |item|
item.created_on = Time.now
item.created_by = active_user.pk
end
end
@item.updated_on = Time.now
request.params.each do |field,value|
if @item.respond_to?( "#{field}=" )
@item.send( "#{field}=", value )
end
end
@item.save
end

# _edit_item.xhtml
<form action='update_item' method='post'>
<input type='hidden' name='item_id' value='#{@item.id}' />
<input type='text' name='some_field' value='#{@item.some_field}' /
>

<button type='submit'>#{@action==:new ? 'create item' : 'save
changes'}</button>
</form>


If you have any changes that need a valid @item.id, such as setting
fields that change values in another model that this is one_to_many
with the main item, then you should do them after you save the item in
update.

For example, in one of my projects I have:
class MyItem < Sequel::Model
many_to_many :tags
def tag_names=( space_separated_string )
# ...make them into an array of valid Tag items
@new_tags.each do |tag|
# This requires self to have a valid ID so that
# the association can be set up.
self.add_tag( tag )
end
end

So my #update_item actually looks more like this:
def update_item
@item = MyItem[ request['item_id'] ]
item_is_new = !@item
unless @item
Ramaze::Log.debug( 'Creating new item!' )
@item = MyItem.new do |item|
item.created_on = Time.now
item.created_by = active_user.pk
end
end
@item.updated_on = Time.now
request.params.each do |field,value|
next if item_is_new && field=='tag_names'
if @item.respond_to?( "#{field}=" )
@item.send( "#{field}=", value )
end
end
@item.save

# Do this after saving so the right ID is here
if item_is_new && request['tag_names']
@item.tag_names = request['tag_names']
@item.save
end
end

Scott LaBounty

unread,
Jul 2, 2009, 12:31:56 PM7/2/09
to ram...@googlegroups.com
Thanks! That's exactly the kind of code I was looking for. I was missing the render_partial.
--
Scott
http://steamcode.blogspot.com/
Reply all
Reply to author
Forward
0 new messages