Is it possible to redefine {object} within a serializer?

117 views Asked by At

I have users and I have admins, but an admin just references a user. Within the admin, I have admin_roles and each admin_role has many admins. In my AdminRoleSerializer, I have a has_many admins that gets serialized into the AdminRoleUserSerializer like this:

module Admin
  class AdminRoleUserSerializer < ActiveModel::Serializer

    attributes :user_id, :first_name, :last_name, :title, :organization_name

    def user_id
      object.user.id
    end

    def first_name
      object.user.first_name
    end

    def last_name
      object.user.last_name
    end

    def title
      object.user.title
    end

    def organization_name
      object.user.organization_name
    end

  end
end

So I'm passing a collection of admins into the AdminRoleUserSerializer and then iterating over each admin object to pull out the actual user information, and it's not very dry at all. It makes the most sense to pass the admins into that serializer, but it doesn't make sense to have to redefine each attribute of a user like that. Here's a thought:

module Admin
  class AdminRoleUserSerializer < ActiveModel::Serializer

    object = object.user
    attributes :id, :first_name, :last_name, :title, :organization_name

  end
end

Is something like that possible now? Is this something that makes sense?

1

There are 1 answers

1
Eli Duke On BEST ANSWER

It is possible to monkey patch the object being passed into a serializer, like so:

module Admin
  class AdminRoleUserSerializer < ActiveModel::Serializer

    def initialize(object, scope)
      super
      @object = object.user
    end

    attributes :id, :first_name, :last_name, :title, :organization_name

  end
end

That will change each admin into a user and then you can simply set the list of user attributes that you want. It works, but it's a bit kludgy.

You're probably better off just changing what you are passing into your AdminRoleUserSerializer. In the AdminRoleSerializer instead of passing a collection of admins to the AdminRoleUserSerializer, you can map the admins into a collection of users like so:

object.admins.map(&:user)

Now your AdminRoleUserSerializer will receive a collection of users to iterate over instead of admins.