Skip to content

Instantly share code, notes, and snippets.

@richmolj
Created November 23, 2016 21:13
Show Gist options
  • Save richmolj/75a1c89f1d19349a3d37ea6040cba213 to your computer and use it in GitHub Desktop.
Save richmolj/75a1c89f1d19349a3d37ea6040cba213 to your computer and use it in GitHub Desktop.
# Let's say you can only see employee salaries if you are a manager, an empployee in HR, or if you have a special privilege
# This employee also has "rank", their stack ranking, that should only be visible to managers
# This populates a grid in an internal admin screen
# The salary column is hidden if you shouldnt see it
#
# An employee also has reviews (managerial reviews) that follow the same logic.
# Click a row to expand and see reviews.
# Ember data model
#
# export default DS.Model.extend({
# name: DS.attr('string'),
# salary: DS.attr('number'),
#
# reviews: DS.hasMany()
# })
#
# this.store.query('employee', { include: 'reviews' })
#
# GET /employees?include=reviews
# So I feel like I'd need this type of logic in controller/somewhere:
can_see_salary = false
if current_user.manager? || current_user.hr? || current_user.privileged?(:salary)
can_see_salary = true
end
can_see_rank = false
if current_user.manager?
can_see_rank = true
end
# Then some logic to pick the correct employee serializer
serializer = EmployeeSerializer
serializer = EmployeeWithRankSerializer if can_see_rank
serializer = EmployeeWithRankAndSalarySerializer if can_see_salary
# Even once I did that, I now need to pick the right serializer
# for the *review relation*. I'm not even sure how to do this
# I'd propose either passing the context (in my case, controller)
# or instance_evaling within that context, ie:
class SerializableEmployee < JSONAPI::Serializable::Resource
attribute :name
attribute :salary do
# here in instance_evaling the context, which is controller, which has current_user
# this would probably have different logic since I don't want to return nil, I want to avoid the
# field altogether.
object.salary if current_user.manager? || current_user.hr? || current_user.privileged?(:salary)
end
has_many :reviews # no need for custom serializer specification
end
@beauby
Copy link

beauby commented Nov 23, 2016

I would do serializers based on the roles, rather than their capabilities. At the end of the day, you are presenting different data depending on the role. Ideally, you would have different entities representing those, for each of which there would be a serializer (leading to a bit more code but more flexible and less bug prone).
How about SerializableEmployeeForManager, SerializableEmployeeForHR, etc. ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment