For my phase 4 project, my idea was to have a social-media-like app where the user logged in from a specific location. A user's interacting network would be limited to only the location they are logged in from. Because location was part of the login process, the session needed to store location data as well as user data. And then passing this to the client side becomes more difficult since two objects are passed.
To start from the basics, I setup an auto-login route based on the session. I knew this would need to be a custom route, given my output would need to return user data and location data, so I opted to create a custom controller function instead of the standard show function. My GET route in ruby would be:
get '/me', to:'users#auto_login'
And my client side would run a useEffect to fetch this route. Now, if I only needed user data, my auto_login function could be:
def auto_login
user = User.find_by(id: session[:user_id])
if user
render json: user
else
render json: { error: 'User not found'}, status: :unauthorized
end
end
How could I get the location of the last session for the auto-login to function? I'm not passing any parameters at the moment... Location is tied to the User through relationships, but this would give me all locations, not the one of the last session. Currently, my function works because I am able to get the user id from the session data. If I stored the location id to session, I could do the same thing. So I go back to my sessions controller create method.
Nothing too complicated, the same way I stored my user to the session, I will store the location to the session. If the password is authenticated, it will stored the location id from params to session[:location_id].
def create
user = User.find_by(username: params[:username])
location = Location.find(params[:location_id])
if user&.authenticate(params[:password])
session[:user_id] = user.id
session[:location_id] = location.id
render json: user, status: :created
else
render json: { errors: "Invalid username or password" }, status: :unauthorized
end
end
Now, going back to my UsersController where I have my auto_login method, I am able to get the session location by running:
Location.find_by(id: session[:location_id])
Now I just need to return both objects to the client. I think the cleanest way would be to create a new, nested object, and then render as json. My final auto_login function is:
def auto_login
user = User.find_by(id: session[:user_id])
location = Location.find_by(id: session[:location_id])
if user
result = {user: user, location: location}
render json: result
else
render json: { error: 'User not found'}, status: :unauthorized
end
end
Top comments (0)