Creating a child object - handling the parent reference?

All,

Looking for a best practice here. I have an object, List, that I’m
editing in a form. List is a collection of Target objects.

One of the things that I can do in my List edit is create a new Target.
I am trying to come up with the best way to be able to assign my new
Target object to my List object.

I know that I can:

  1. Create a hidden field in my form that holds the list id and get
    access to it that way in my “create_target” action.

  2. I could store the list id in the session (in a key such as
    “current_list”) as soon as I hit the “edit list” function and have
    access to it that way.

Are there any other options?

Anyone care to advise on a best practice?

Thanks,
Wes

Quickly, here’s what I did:

Parent controller (ListController):

def add_target
flash[:current_list_id] = @target_list.id
redirect_to(:controller => ‘target’, :action => ‘create’)
end

Child controller (Target):

def create
@target = Target.new
@target.target_list = TargetList.find(flash[:current_list_id]) if
flash[:current_list_id]
session[:new_target] = @target
render(:action => ‘edit’)
end

I think this, and allowing for quick on-screen messages is the only
reason to use the flash - but it is very handy for these cases when I
have complete control over the requests.

Fear not, the session[:new_target] object is set to nil upon the
successful save of the target.

Thanks,
Wes

Max,

I see your point on the session issue and I can agree on your two
potential solutions for getting around using the flash.

However, the session[:new_target] object is really what I’d call a “form
bean” in the Java world - it is the new target object until it
successfully gets created in the database upon the first successful
save.

I’m not a big fan of creating stuff in the database until it is really
necessary, so I need someplace to store the new target until it is
saved. What are your thoughts?

In general, the synchronization issue that you bring up where one user
may interact through my application through many browsers is valid.
Although I think you probably run into this issue as soon as you store
anything in the session, not just the stuff that I was proposing. I
can’t remember if/how we ever got around that in Java - based Web apps.
I believe a custom request - synchronization scheme would be required,
no?

Wes

On 10/3/06, Wes G. [email protected] wrote:

I know that I can:
Anyone care to advise on a best practice?

Storing this kind of information in the session is generally a bad
idea. There are always those power users that insist on opening
several browser windows for the same session. In that case, you open
up the possibility of invalid data being written to the db. Of course,
you can get around this with some sort of request key mechanism that
detects double posting, but that’s more trouble than it’s worth.

Two ways of handling this are posting the parent id in a hidden field,
or making the parent id part of the url the form is posted to:
/targets/add_to_list/3 where 3 is the id of the list. Or (with slight
semantic breakage of the controller separation) /lists/add_target/3
where the target creation is handled in the lists_controller code.

Cheers,
Max

I am trying to come up with the best way to be able to assign my new
Target object to my List object.

Below is what I do. Can someone enlighten me if this is the “right” way
to do things? I remember hearing some philosophies on when to send data
with GET versus POST. I like to POST the “new data” and send the parent
info in the URL…

For your new target form:

<%= form_tag :controller => ‘target’, :action => ‘create’, :list =>
@list.id %>

In your target ‘create’ method:

if params[:list]
@list = List.find(params[:list])
@target = Target.new(params[:target])
@target.list = @list
@target.save
end