Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

overriding rendering methods in devise_token_auth #597

Closed
omar28 opened this issue Apr 3, 2016 · 14 comments
Closed

overriding rendering methods in devise_token_auth #597

omar28 opened this issue Apr 3, 2016 · 14 comments

Comments

@omar28
Copy link

omar28 commented Apr 3, 2016

I am currently building a rails api and I am using your devise_token_auth.

I’ve been stuck for a while on how to render custom data for user model. Rather than getting a ison like this:

{
"data": {
"id": 316,
"provider": "email",
"uid": "[email protected]",
"name": "olahlou",
"nickname": "olahlou",
"email": "[email protected]",
"score": 2,
"image": null
}
}

Let’s say the user has_many :posts, I would like to apply a user serializer(I am using active model serializers) to render something like (without the “data” key):

{
“id”:316,
“name”:”olahlou”,
“posts”:[{
#first post,
#second post...
}]
}

I’ve read the documentation an I guess I have to override the SessionController#render_create_success but I really don’t know how to do it.

Thank you in advance for your help.

@thelastinuit
Copy link

@omar28

at your 'user' model:

def token_validation_response                                                                                                                                         
  UserSerializer.root = false
  UserSerializer.new(self).as_json
end

This will render your serializer.
Now for the data thingy, you need to look at session_controller:

def render_create_success
  render json: {
    data: resource_data(resource_json: @resource.token_validation_response)
  }
end

that method is what you need to manage.

@thelastinuit
Copy link

Look at:

# config/routes.rb
Rails.application.routes.draw do
  ...
  mount_devise_token_auth_for 'User', at: 'auth', controllers: {
    sessions:  'overrides/sessions'
  }
end

# app/controllers/overrides/sessions_controller.rb
module Overrides
  class SessionsController < DeviseTokenAuth::TokenValidationsController
    def render_create_success
      render json: resource_data(resource_json: @resource.token_validation_response)
    end
  end
end

@thelastinuit
Copy link

@omar28 Please close the issue if that worked for you. Otherwise, let me know so I can help you out ^_^

@omar28 omar28 closed this as completed Apr 5, 2016
@kjakub
Copy link

kjakub commented May 19, 2016

why you inheriting

class SessionsController < DeviseTokenAuth::TokenValidationsController

to override SessionsController ?

it should be class SessionsController < DeviseTokenAuth::SessionsController ?

@adis-io
Copy link
Contributor

adis-io commented Jun 29, 2016

Why resource_data method is not available when I override SessionsController?

I have this error:

NoMethodError (undefined method `resource_data' for #<Overrides::TokenAuth::SessionsController:0x007fc21abe6958>):
  app/controllers/overrides/token_auth/sessions_controller.rb:6:in `render_create_success'

@thelastinuit
Copy link

thelastinuit commented Jun 29, 2016

@kjakub sorry! You are right. I didn't pay attention to that.
@adisos This is what I have:

class Api::V1::SessionsController < DeviseTokenAuth::SessionsController

  def resource_data(opts = {})
    opts[:resource_json] || @resource.as_json
  end

  def render_new_error
    render json: {
      errors: [I18n.t("devise_token_auth.sessions.not_supported")]
    }, status: 405
  end

  def render_create_success
    render json: {
      sponsor: resource_data(resource_json: @resource.userable.token_validation_response)
    }
  end

  def render_create_error_not_confirmed
    render json: {
      errors: [I18n.t("devise_token_auth.sessions.not_confirmed", email: @resource.email)]
    }, status: 404
  end

  def render_create_error_bad_credentials
    render json: {
      errors: [I18n.t("devise_token_auth.sessions.bad_credentials")]
    }, status: 402
  end

  def render_destroy_success
    render json: {
    }, status: 200
  end

  def render_destroy_error
    render json: {
      errors: [I18n.t("devise_token_auth.sessions.user_not_found")]
    }, status: 404
  end
end

It works fine. I made the mistake @kjakub mentioned. Use

DeviseTokenAuth::SessionsController

instead of

DeviseTokenAuth::TokenValidationsController

My bad!

If that works, please close the issue @adisos

@adis-io
Copy link
Contributor

adis-io commented Jun 29, 2016

I know, I solved by defining method resource_data in my controller. But this method was already defined in DeviseTokenAuth::ApplicationController from which DeviseTokenAuth::SessionsController was inherited. Sorry for offtopic, but could somebody explain me?

@thelastinuit
Copy link

Well, the "why this works like that", only the creators/maintainers know. I'm here because I use it and maybe I might be useful.
I would have done somethings in a diff way, though.

@adis-io
Copy link
Contributor

adis-io commented Jun 29, 2016

Well, I found out. I'm using rubygems version, which doesn't have resource_data method.

@thelastinuit
Copy link

Me too! This is strange... any one?

@adis-io
Copy link
Contributor

adis-io commented Jun 29, 2016

I think it's simple because gem author didn't update rubygems for a long time.

@amcamargoc
Copy link

amcamargoc commented Sep 11, 2016

Take a look to this

ROUTES
mount_devise_token_auth_for 'User', at: 'auth', skip: [:omniauth_callbacks], controllers: { sessions: 'overrides/sessions' }

Controller overwrite

module Overrides
  class SessionsController < DeviseTokenAuth::SessionsController
    protected
    def render_create_success
      render json: @resource
    end
  end
end

Credits to Doncote, here original post https://gitter.im/lynndylanhurley/devise_token_auth/archives/2015/12/18

@Meekohi
Copy link

Meekohi commented Apr 5, 2017

I solved this by:

# user.rb
def token_validation_response                                                                                                                                         
    self.as_json(include: :posts)
end

This is pretty easy. The documentation at https://github.com/lynndylanhurley/devise_token_auth#overriding-rendering-methods makes it sound WAY more confusing, it would be great to add a section describing this common and much simpler case (i.e. don't need custom JSON per controller method, just in general for devise-token-auth, but don't want to change it everywhere else in the app).

@jachwe
Copy link

jachwe commented Nov 13, 2019

@Meekohi your answer is working perfectly and solved it for me.
(Unfortunately, I tried all the other ones before scrolling all the way down )
Really hope, people will read the full thread. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants