Advanced usage patterns of ATK Models


One interesting and very useful topic (in book or somewhere else) would be “Advanced usage patterns of ATK Models”.

There could be some advanced real-life examples how to use Models (User / UserActive / UserHistory) and especially references between them and traversal in more advanced and tricky situations.

My real-life example is something along these lines:

  • I have Ticket model (support ticket, table ticket)
  • One ticket can have only one responsible user at the time, but responsible user can
    change and I should keep track of history of these changes per ticket.
  • So I have table ticket_responsible_user with fields
    id,ticket_id,user_id,from_time,to_time. Active responsible user is
    user from this table with to_time=null
  • Ticket->hasMany(ResponsibleUser) will navigate to all responsible (historical and active) user
  • ResponsibleUserActive extends ResponsibleUser + addCondition(to_time, null)

I can’t set Ticket->hasOne(ResponsibleUserActive) because then ATK will want ticket_responsible_user_id field in ticket table which is not my case.
Only way I can think of is still using addExpression in Ticket model which is not nice and will work slow as sub-select all the time

Is there any other way how to navigate from Ticket to active ResponsibleUserActive ? It’s like 1:1 relation I guess.
If I set Ticket->hasMany(ResponsibleUserActive), then it’s not right by design, because ticket can have only one responsible user at the time, and 1:n relation will not help in any way to simply navigate from Ticket to active ResponsibleUser model.

Any ideas?


Hi Imants.

Just wanted I’d mention this: as it has some interesting usage examples.


Another interesting project:


I Might be wrong. But in one of our project we override ref function

By using Ticket->hasMany(ResponsibleUser) is enough
but in ref function we just checked for a virtual relation ResponsibleUserActive.

if asked for such we just used

return $this->ref(ResponsibleUser)->addCondition()->tryLoadAny()

But still I think a seperate section of such real life problems will be a good way.


is not working … getting 404


Dig in with :grinning: