Skip to content

Associations

sergeych edited this page Aug 21, 2012 · 7 revisions

Associations are declared in the 'owner' table, like has_many: in rails (activerecord):

class Order extends prego.Table

class Person extends prego.Table
    @hasMany(Order [,createParams])

This declaration requires that table orders have integer person_id column as a foreign key, usually, you declare it in migration sql somehow like:

create table orders(
   ...
   person_id integer references persons on delete cascade,
   ...
);
create index ix_orders_persons on orders(person_id);

Don't forget creating foreign indexes! Note that Order model class must be declared before creating a reference. The above declarations creates few reference functions in Order and Person classes to create, build, and fetch associated objects.

Optional createParams argument is discussed at the end of thi page. There is a minimal support for polymorphic associations too.

Fetching associated objects

order.person (err, person) ->
   # if !error person is either null or Person instance

person.orders_all [params,] (err, orders) ->
   # optional first arg is a { where:... values:...} hash (see below)
   # if not err then orders is an array of Order instances (that can be empty, of course).

person.orders_each [params,] (err, order) ->
   # optional first arg is a { where:... values:...} hash (see below)
   # will be called with non-null order instance per each associated object
   # then with order == null when no more objects left.

params may contain additional conditions, e.g.

person.orders_all { where: 'something < $2 and other != $3', values: [10, 'nonono'] }, (err, orders) -> # err || orders that match conditions

arguments are specified from $2 - $1 is reserved for the foreign id.

to retreive associated object from the 'beloged' object, just use its owner name:

order.person (err, person) -> # err or valid Person instance hete

Please note that there is no associated objects cache (but SQL statements to retreive are prepared and cached, instead, so every time you ask for it, it would be retreived from DB. This is made by purpose, though, as author can implement much more effective caching that universal one that would slow down all operations and cause problems with cache invalidation.

Creating associated objects

To create associated object, just assign its personId field:

new Order({personId: person.id, ...}).save (err) -> # if not err, here person.orders.all will retreive non empty collection

Or build it automatically, providing oprional hash with field values:

order = preson.orders_build { qty: 1, name: 'something' }
order.save (err) ->
    # err or saved

Or combine these two:

person.orders_create { qty: 5, name: 'foobars' }, (err) ->
    # err or order is saved

@hasMany( model, params ) in details

model should be an prego.Table descendant, defined before creating an association. params is a optional hash of argumenrs:

Clone this wiki locally