I have an app that I've built with ruby on rails in the backend with the front end being simple rails views. I'd like to add react to the front end to make it look nicer. I have read about using the react-rails gem, or creating a new react app and using the rails app as API only, so I'm wondering what the best approach is. I also used the devise ruby gem for handling user auth-- but I have seen some things that suggest I need to use the devise_token_auth gem if I want to go the rails API route... How would you approach adding a react front end to a fully built rails app?
Asked
Active
Viewed 846 times
1 Answers
1
Ive done both styles that you mentioned, in my own experience i liked more having a separated react project and using a rails api maybe because i use docker for my builds and had several problems when i used the rails-react gem and webpacker but the advantage is that you wont have to do 2 deploys, in both approaches you would have to setup APIs.
ps : webpacker precompiles in rails can get pretty heavy sometimes
For both you will need a devise JWT token for the authentication tho, here is a nice tutorial on how to set it up
if you want to have both auth methods (html & json) you can use something like this in your sessions controller
class Users::SessionsController < Devise::SessionsController
respond_to :json, :html
# before_action :configure_sign_in_params, only: [:create]
def create
if request.format.html?
super
# super {
# cookies[:token] = current_token || ""
# }
else
resource = User.find_for_database_authentication(email: params[:email])
return invalid_login_attempt unless resource
if resource.valid_password?(params[:password])
sign_in(resource, store: false)
@payload = [resource, current_token]
render(status: 200, success: true, json: @payload)
else
invalid_login_attempt
end
end
end
def invalid_login_attempt
warden.custom_failure!
render json: {
success: false,
message: 'Error with your email or password'
}, status: 401, status: :unauthorized
end
def current_token
request.env['warden-jwt_auth.token']
end
private
def respond_with(resource, _opts = {})
if request.format.html?
super
else
render status: 401, success: false, json: { error: 'No autorizado' }
end
end
def respond_to_on_destroy
if request.format.html?
super
else
head :ok
end
end
end
there is probably a best way to do this but works for me lol

André Kraüss
- 73
- 2
- 8