I'm using Single Table Inheritance (STI) in my Rails app for the User object. There is an API response that is including all attributes of my User subclasses (Teacher, Student) except for type
. I believe this is due to using the render json
method, as I was able to find some other questions from a long time ago with this issue, but haven't found any solutions.
How do I prevent Rails from suppressing the user type attribute in the json response?
My controller is returning:
render json: {
logged_in: true,
user: @user,
}
The user
model has the following schema (taken from schema.rb):
create_table "users", force: :cascade do |t|
t.string "email"
t.string "username"
t.string "password_digest"
t.string "first_name"
t.string "last_name"
t.string "type"
t.string "phone_number"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
And my JSON response received from the Rails API for the user object was:
"logged_in":true,"user":{"id":2,"email":"[email protected]","username":"Student","password_digest":"redacted","first_name":"Test","last_name":"Test","phone_number":"18008008100","created_at":"2024-06-08T02:35:27.382Z","updated_at":"2024-06-10T05:44:14.299Z"}}
Why does it contain everything except for the type
attribute?
Why does it contain everything except for the type attribute?
Because type
attribute, aka User.inheritance_column
, is skipped:
options[:except] |= Array(self.class.inheritance_column)
https://github.com/rails/rails/blob/v7.1.3.4/activerecord/lib/active_record/serialization.rb#L18
You could use :methods
option to add type
back:
render json: {
logged_in: true,
user: @user.as_json(methods: :type)
}
or render json view:
# app/views/users/show.json.jbuilder
json.logged_in true
json.user do
json.extract! @user, :id, :email, :type
end