Next iteration of serializers
### Description I recently though that our serializers (`app/serializers`) might need a next iteration with some minor refactoring. This is how pipelines and environments serializers look like at the moment: * [`pipelines_serializer.rb`](https://gitlab.com/gitlab-org/gitlab-ce/blob/ac06070147f23909dfb5d3468a17a29e6b0cd447/app/serializers/pipeline_serializer.rb) * [`environments_serializer.rb`](https://gitlab.com/gitlab-org/gitlab-ce/blob/ac06070147f23909dfb5d3468a17a29e6b0cd447/app/serializers/environment_serializer.rb) We have more serializers, but these are most complicated ones at the moment. It appears that using serializers to set some constraints / extensions to `ActiveRecord::Relation` objects which are passed to `Serializer#represent(resource)` is a convenient thing to do. How we use `PipelinesSerializer` now: ```ruby pipelines: PipelineSerializer .new(project: @project, user: @current_user) .with_pagination(request, response) .represent(@pipelines), ``` This represents paginated resource, but in other places of GitLab we still do not paginate pipelines, so we don't call `with_pagination` on the serializer object. The problem with this approach is that we pass `@resource` after we set pagination, which means that we have to somehow memoize the pagination request, and apply pagination after this is done. In [the new environments serializer](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8928) we want to sometimes group some environments into folders, it looks quite similar. But code like this: ```ruby def represent(resource, opts = {}) resource = paginate(resource) if paginated? if itemized? itemize(resource).map do |item| # ... end else super(resource, opts) end end ``` does not scale very well, because we have to add `itemized?`, `paginated?` for each condition. Would it be better to add pagination to the `ActiveRecord::Relation` object once we call `with_pagination`? Changing the `resource` object when someone calls `with_folders` might be a good solution as well. This would mean that we should refine serializers and pass the `ActiveRecord::Relation` object to the initializer and set `RequestAwareEntity` parameters with method like `.with_request(user: @current_user, project: @project)`. ### Proposal Refine serializers to support code like: ```ruby PipelineSerializer.new(@pipelines) .with_request(user: @user, project: @project) .with_pagination .with_something_else .represent! ``` [Fluent interface](https://en.wikipedia.org/wiki/Fluent_interface) like this may simplify the underlying implementation. I remember @DouweM didn't like this solution when we introduced serializers in the first place, but I wonder what do you and @rymai think about it since we know a little more about serializers now, once we have few implemented already.
issue