can you share you controller code for the relationship route?
Also, if I understand correctly, are you using a custom relationship so that zones appear twice in the related data tab, and it enables you to display different columns?
Or are the controllers for the two smart relations I’m seeing in the screenshot different? (do they filter different zones?)
router.get('/customers/:customerId/relationships/customerZones', (request, response, next) => {
const {customerId} = request.params;
const limit = parseInt(request.query.page.size, 10) || 20;
const offset = (parseInt(request.query.page.number, 10) - 1) * limit;
const recordsGetter = new RecordsGetter(models.zones);
const include = [{
model: models.buildings,
as: 'building',
where: { customerIdKey: parseInt(customerId) },
}];
const findAll = models.zones.findAll({
include, // CHANGED FROM includeFindAll AND WORKS NOW
offset,
limit,
});
// count all customers for pagination
const count = models.zones.count({ include });
// resolve the two promises and serialize the response
Promise.all([findAll, count])
.then(([records, recordsCount]) =>
recordsGetter.serialize(records, { count: recordsCount }))
.then((recordsSerialized) => response.send(recordsSerialized))
.catch(next);
});
The second zones relationship that appears is a proxy collection that is used to avoid loading too many columns for both performance and information overload reasons.
Well the issue with smart relationships, is that you have full control of the reply…
You can access the frontend filters and search parameters in the query string (request.search, request.searchExtended, and request.filters)
So if you need filters and search to work, you would need to implement them yourself on the controller (like you did with pagination), but it’s far from trivial if you do it from scratch
Forest Admin exposes services (which are largely undocumented… sorry for that) for this purpose
Here is an example which you can adapt from (using books and reviews)
const { RecordsGetter, RecordsCounter } = require('forest-express-sequelize');
const { books, reviews } = require('../models');
router.get('/books/:book_id/relationships/reviewsagain', (request, response, next) => {
// Make filter that keeps only the reviews of book(id == X)
let filters = JSON.stringify({
field: 'book:id',
operator: 'equal',
value: request.params.book_id
});
// Merge filter with the filter on the query string, if one is provided
if (request.query.filters) {
filters = `{"aggregator":"and","conditions":[${request.query.filters},${filters}]}`
}
// Get records
const recordsGetter = new RecordsGetter(reviews);
const findAll = recordsGetter.getAll({...request.query, filters});
// Count records
const recordsCounter = new RecordsCounter(reviews);
const count = recordsCounter.count({...request.query, filters});
// resolve the two promises and serialize the response
Promise.all([findAll, count])
.then(([reviewFound, reviewsCount]) =>
recordsGetter.serialize(reviewFound, { count: reviewsCount }))
.then((recordsSerialized) => response.send(recordsSerialized))
.catch(next);
});