Taylor Otwell Wed Dec 22 09:31:31 -0500 2010

Subject: Saving related objects?

How does PHP ActiveRecord handle saving related objects. For example, let's say I have a "User" that has many "Phone Numbers". When I call "$user->save()", does it save the phone numbers associated with that user, or does each object have to be persisted individually?

If there is a section in the docs about this a link would be greatly appreciated!

Thanks!


Andrea Franceschini Tue Dec 28 06:25:43 -0500 2010

Hi. I'd really like this feature, and as far as I can see, it seems to be quite trivial to be implemented, though it'd be an inefficient implementation. Basically, my idea is going at https://github.com/kla/php-activerecord/blob/master/lib/Model.php#L757 and adding a couple (or more) of foreach over the owned associations, and save them whenever they're dirty.

It'd be more efficient to build a sql query to perform this stuff in a single call to the database, but I'm not (yet) enough familiar with SQLBuilder's and the whole project's internals to propose such a solution.

While we're discussing this, it seems to me that there's no support for nested attributes. Is this correct?

Taylor Otwell Tue Dec 28 14:04:49 -0500 2010

I think your idea would work. But, like you said, I'm not sure it would be the most efficient, especially for large datasets. I would be interested to hear one of the author's thoughts on this.

What do you mean by nested attributes?

Andrea Franceschini Wed Dec 29 04:31:02 -0500 2010

I'm not sure that "nested attributes" is the proper wording, though I borrowed it from Rails. Anyway, it's the same thing you mean by "related object". Generally speaking, the associations of an entity are nested attributes.

The point is that in Rails you can build a form with fields for such attributes, and when it gets sent back to the server, the handler action can get the array generated by the form and pass it to the main model, and this array contains not only the attributes for that model, but also the attributes for the associated models.

For example, consider an Invoice model that has many Items. The form would send back something like

invoice[id] = 42
invoice[description] = Lorem ipsum dolor
invoice[paid] = 1
invoice[items_attributes][0][description] = First item
invoice[items_attributes][0][price] = 100
invoice[items_attributes][1][description] = Second item
invoice[items_attributes][1][price] = 250

and so on. Then, in Rails, you'd do something like

def update
invoice = Invoice.find(params[:id]) # the id comes from the URL, not from the form
invoice.update_attributes(params[:invoice]) # and this is the array that comes from the form
end

and the ActiveRecord::Base component (educated guess) takes care of updating the model's attributes and any relevant associated object.

I hope I've been clear :)

Jacques Fuentes Wed Jan 05 21:42:02 -0500 2011

Taylor,

Unfortunately the answer is "No" to both of your questions. Saving related objects is relatively easy and something I'd like to support. I'd also like to support nested attributes, but it would require more work and testing.

Would you mind opening github issues for your requests? That's where we address features/bugs.

Thanks.

Andrea Franceschini Thu Jan 06 05:44:24 -0500 2011
Stefan W Tue Jan 11 09:04:36 -0500 2011

The best implementation of this I've used is probably Doctrine. Maybe look at that for some pointers.

In that you do things like:

$user->phonenumber[]->number = 12345;
$user->phonenumber[]->number = 67890;

or I think you can do something like:

$phonenumber = new PhoneNumber;
$user->link($phonenumber);

(1-6/6)