Chicago Boss home

The Chicago Boss API is mostly stable, but still might change before 1.0.

Jump to: Generated instance methods   Associations (belongs_to, has)   Save hooks

BossRecords are specially compiled parameterized modules that follow the "active record" pattern. BossRecords go into your project's src/model/ folder and will have functions generated for saving them into the database and for accessing related BossRecords. Important aspects of BossRecords:

Generated functions

Generated instance functions of a BossRecord include:

save() -> {ok, SavedBossRecord} | {error, [ErrorMessages]}

Saves this boss_record record to the database. The returned record will have an auto-generated ID if the record's ID was set to 'id'. Performs validation first, returning ErrorMessages if validation fails. See validate/0.

validate() -> ok | {error, [ErrorMessages]}

Validates this boss_record without saving to the database. Errors are generated from this model's validation_tests/0 function (if defined), which should return a list of {TestFunction, ErrorMessage} tuples. For each test, TestFunction should be a fun of arity 0 that returns true if the record is valid or false if it is invalid. ErrorMessage should be a (constant) string that will be included in ErrorMessages if the associated TestFunction returns false on this particular boss_record.

set(AttributeProplist[{Attribute::atom(), Value}]) -> BossRecord

Set multiple record attributes at once. Does not save the record.

set(Attribute::atom(), NewValue) -> BossRecord

Set the value of a particular attribute. Does not save the record.

attributes() -> [{Attribute::atom(), Value::string() | undefined}]

A proplist of the boss_record parameters and their values.

attribute_names() -> [::atom()]

A list of the lower-case boss_record parameters.

reset(Counter::atom()) -> ok | {error, Reason}

Reset a counter to zero

incr(Counter::atom()) -> ::integer()

Atomically increment a counter by 1.

incr(Counter::atom(), Increment::integer()) -> ::integer()

Atomically increment a counter by the specified increment

belongs_to_names() -> [{::atom()}]

Retrieve a list of the names of belongs_to associations.

belongs_to() -> [{::atom(), BossRecord}]

Retrieve all of the belongs_to associations at once.

id() -> Id

Returns the value of Id

Other getters and setters are generated based on the parameters of your BossRecord.

Associations

Special associations are generated from the following module attributes:

-belongs_to(foo).

Requires a matching FooId in the parameter list. Adds a function foo() which returns the BossRecord (of any type, usually foo) with ID equal to the current BossRecord's FooId.

-has({bar, 1}).
-has({bars, Count}). % Count > 1
-has({bars, many}). % alias for 1 million

Generates a function bar() or bars() which returns up to Count "bar" BossRecords with FooId equal to this BossRecord's ID. If Count is greater than 1, also creates first_bar() and last_bar() which return the first and last items in the association.

When Count is not equal to 1, has can also take a proplist of options as the third element in the tuple:

-has({bars, many, [{sort_by, first_name}]}).

Valid options are:

Note that Time and float attributes are stored internally as integers, so sort them with num_ascending or num_descending.

The two above attributes work similar to belongs_to and has_many/has_one in Rails.

-counter(foo_counter).

Generates a function foo_counter() which returns the value of the counter, initialized to zero. Each BossRecord may have an unlimited number of counters. Manipulate the counters with reset and incr above.

SPECIAL NOTE: Everything in the Model directory will be compiled as a BossRecord rather than as a regular Erlang module; you don't need to do or declare anything special.

Save/delete hooks

You can specify logic to be run anytime a BossRecord is saved, or before it is deleted. Just define one or more of these functions in your module:

before_create/0 and before_update/0 should return one of:

before_delete/0 should return ok to continue with the deletion, or {error, Reason} to abort the deletion.

Return values for the other hook functions are ignored.