On p. 299 of the current Rails book it says that “Active Record takes
care of saving all the dependent child rows when you save a parent
row.” So, when I add a row to the table that has “belongs_to” in its
model, shouldn’t the table with the “has_many” be updated with data
from the foreign key? If not, how do I save data from a form into
more than one table? (And, maybe unfairly expanding into a second
question, how could I put fields from multiple tables on a web page so
that when it is filled out the values will go into various tables?)
In both of these forms of questions I’m trying to get an answer to how
data that will go into multiple tables can come from one web page. I
hope my statement of the problem isn’t too confusing.
Thanks,
Barney
It’s a common problem and there’s isn’t one answer.
I’ll give you three:
- If the objects have relationships to eachother, specify
accepts_nested_attribtues_for in your models and then let active record
do its thing (what you described in your post works only if you do
accepts_nested_attribtues_for in your models). If class Apple has_one
:orange and also accepts_nested_attributes_for :orange, you can have
fields on your form like this:
text_field_tag “apple[orange][skin]”, “peeled”
- Hack together a single form that contains parameters from two
different objects. On the controller, you’ll get params[:apple] and
params[:orange]
You can’t use form_for as a resource oriented form_for, but you can use
form_for and just give the fields custom names that are scoped to the
objects you want to scope
text_field_tag “apple[variety]”, “golden delicious”
text_field_tag “orange[skin]”, “peeled”
In your controller, you would do something like this
@apple.update_attributes(params[:apple])
@orange.update_attributes(params[:orange])
That’s a little hacky, to be frank. If you were doing this with two
distinct objects I might do a quick hack like that, but it’s not
scalable.
- Take the example of a Registration process. Let’s say you want to
register a camper for summer camp (nice July-appropriate example). One
thing you can do is create a Registration object that synthesizes all
the other things together. If your Registration object itself has
database records, you can use something like strategy #1 above. But,
keep in mind that your Registration object doesn’t have to be
ActiveRecord (or have database records) at all. Experiment with (or just
think about) making a Ruby model object that has no active record
component.
In that paradigm, the Ruby model object (that does not inherit from
active record and also does not have database records), represents the
transaction. You won’t keep it around after the controller it done
(because it will be gone from memory after the execute is done). But you
can instantiate it, work with it, write business logic on it, pass it
messages (call methods) and let it update other objects in your system.
That would be a more globalized strategy if say, you wanted to submit
one form and have it touch 5 different objects.
-Jason
Thanks Jason,
The first option sounds like it would be the most consistent with
Rails so I’ll read up on accepts_nested_attributes_for and try to make
that work.
Barney
On Jul 14, 5:15pm, Jason Fleetwood-Boldt [email protected]