Is it possible to access fields in a joined table in Vapor?

烈酒焚心 提交于 2020-01-14 14:36:27

问题


I have a Persons table and an Events table that are related via an Attends table, such that a record exists the Attends table when I wish to record the fact that a person is due to attend a particular Event in a particular role (e.g. organiser, etc.):

Persons
+----+-------------+
| id | surname     |
+----+-------------+
|  1 | Robinson    |
|  2 | Savage      |
...

Events
+----+-----------------------+
| id | name                  |
+----+-----------------------+
|  1 | Half Term Competition |
|  2 | Christmas Competition |
...

attends
+---------+----------+--------+
| eventId | personId | roleId |
+---------+----------+--------+
|       1 |        1 |      1 |
|       1 |        2 |      6 |
...

I want to produce a list of who is going and what they are doing at an event, but I can't find a way of doing it using .join() in Vapor query. It seems that you can filter on the joined table, but not include any of the fields. Am I missing something or is this impossible?

I've tried many variations on the theme of:

Person.join(Attends.self).filter(Attends.self,Event.foreignIdKey == eventId)

I get the correct Person records, but no way of accessing what their 'role' is from the joined Attends record.

If I do a raw query, then it returns a Node representation. I can easily view this using Leaf, but it is not at all obvious how to iterate over it in the way I would like to generate a PDF with images, etc.


回答1:


The Vapor docs for Fluent relations is probably what you are looking for.

From what I can tell, you are using a Many to Many (sibling) relation, so this code might be what you want:

extension Persion {
    var roles: Siblings<Persion, Role, Pivot<Person, Role>> {
        return siblings()
    }
}

Then get the roles:

let roles = person.roles.all()

I might have got this wrong as I can't see your code, but it should give you some pointers.




回答2:


The trick here is to make sure you are taking advantage of joins in the database and not doing individual queries for each relation result - which would not be optimal.

I think this is a fairly new(ly documented) feature: https://docs.vapor.codes/3.0/fluent/querying/#join

This allows the following type of query:

Client.query(on: conn).join(\Client.companyId, to: \Company.id)
    .filter(\.attr1 > 12)
    .filter(\Company.name == "ACME")
    .alsoDecode(Company.self)
    .all()

This code returns a tuple of (Client,Company). I'm not sure how it handles many-to-one relations or whether each duplicate reference is the same class instance.



来源:https://stackoverflow.com/questions/46962166/is-it-possible-to-access-fields-in-a-joined-table-in-vapor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!