Rails Adding Attributes to JSON Serializer

1.2k views Asked by At

I had a model that should be rendered as JSON, for that I used a serializer

class UserSerializer
  def initialize(user)
    @user=user
  end

  def to_serialized_json
    options ={
      only: [:username, :id]
    }

    @user.to_json(options)
  end
end

when I render json: I want though to add a JWT token and an :errors. Unfortunately I am having an hard time to understand how to add attributes to the serializer above. The following code doesn't work:

def create
    @user = User.create(params.permit(:username, :password))
    @token = encode_token(user_id: @user.id) if @user     
    render json: UserSerializer.new(@user).to_serialized_json, token: @token, errors: @user.errors.messages
end

this code only renders => "{\"id\":null,\"username\":\"\"}", how can I add the attributes token: and errors: so to render something like this but still using the serializer:

{\"id\":\"1\",\"username\":\"name\", \"token\":\"eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.7NrXg388OF4nBKLWgg2tdQHsr3HaIeZoXYPisTTk-48\", \"errors\":{}}

I coudl use

render json: {username: @user.username, id: @user.id, token: @token, errors: @user.errors.messages}

but how to obtain teh same by using the serializer?

3

There are 3 answers

0
darkash On BEST ANSWER
class UserSerializer
  def initialize(user)
    @user=user
  end

  def to_serialized_json(*additional_fields)
    options ={
      only: [:username, :id, *additional_fields]
    }

    @user.to_json(options)
  end
end

each time you want to add new more fields to be serialized, you can do something like UserSerializer.new(@user).to_serialized_json(:token, :errors)

if left empty, it will use the default field :id, :username

if you want the json added to be customizable

class UserSerializer
  def initialize(user)
    @user=user
  end

  def to_serialized_json(**additional_hash)
    options ={
      only: [:username, :id]
    }

    @user.as_json(options).merge(additional_hash)
  end
end

UserSerializer.new(@user).to_serialized_json(token: @token, errors: @user.error.messages)

if left empty, it will still behaves like the original class you posted

0
WALVISK On

i prefer to use some serialization gem to handle the serialize process like

jsonapi-serializer https://github.com/jsonapi-serializer/jsonapi-serializer

or etc

0
ogelacinyc On

Change to_json to as_json, and merge new key-value.

class UserSerializer
  def initialize(user, token)
    @user=user
    @token=token
  end

  def to_serialized_json
    options ={
      only: [:username, :id]
    }

    @user.as_json(options).merge(token: @token, error: @user.errors.messages)
  end
end