Environment:
Rails: 3.2.12
Ruby: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
In my routes.rb, I have:
match '/attendance', to: "attendance#attendance_dashboard"
In my attendance_controller.rb, I have:
before_filter :authenticate_user!
before_filter :allow_only_if_admin
def attendance_dashboard
logger.info("File: #{__FILE__} -- Line: #{__LINE__}")
#registered_and_not_checked_in = get_registered_and_not_checked_in()
end
I am running on the test system, so logger.info should write to the test.log file.
When I run the /attendance action, I get 500 error, and here's what I see in the test.log file:
Started GET "/attendance" for 73.169.212.94 at 2015-02-06 15:11:06 +000
Processing by AttendanceController#attendance_dashboard as HTML
[1m[35mUser Load (0.4ms)[0m SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1
Completed 500 Internal Server Error in 215ms
I was expecting to have the logger info requested logged to the test.log file, but it's not there, so I'm failing prior to that. Any ideas?
Solution:
The issue was not with the code, it was that user #2, who is signed in as an admin, has a JSON record in his DB record that was failing to unpack properly. Once that was fixed the issue went away.
Related
I'm developing a small application using Ruby on Rails and using Devise for authentication. I've two login systems setup and one is user and the other one is employee
When logging in using correct email and password, devise sends the correct redirect to path back but it gets stuck there. Nothing continues unless I refresh the page. But once I refresh it, it will happily go to the redirect path and even if after logging out in the same browser tab and then logging back in works. But if I close the tab and then load the application in a new tab, it doesn't work.
Following is the rails server output when logging in,
Started POST "/employees/sign_in" for ::1 at 2020-06-21 18:21:50 +0530
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"Pr0k+3+FfU72BcwTVRhWxQYBTD/zcv5+QBdWuovDRd4+yGxC1OBWmvAscWJbnog2vVTLpbPM2xOwVxGC3UsLRg==", "employee"=>{"email"=>"employee#example.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
Employee Load (0.4ms) SELECT "employees".* FROM "employees" WHERE "employees"."email" = $1 ORDER BY "employees"."id" ASC LIMIT $2 [["email", "employee#example.com"], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:23
CACHE Employee Load (0.0ms) SELECT "employees".* FROM "employees" WHERE "employees"."email" = $1 ORDER BY "employees"."id" ASC LIMIT $2 [["email", "employee#example.com"], ["LIMIT", 1]]
↳ app/controllers/application_controller.rb:23
Redirected to http://localhost:3000/employee/dashboard
Completed 302 Found in 818ms (ActiveRecord: 0.4ms)
I'm not sure why this happens and hitting a dead end when trying to find anything related to this error.
Following is the code for my after_sign_in_path function
def after_sign_in_path_for(resource)
set_flash_message! :alert, :warn_pwned if resource.respond_to?(:pwned?) && resource.pwned?
set_root
# super
end
Here set_root function returns a String with the path for the redirect.
Version information
Ruby version - ruby 2.6.0p0 (2018-12-25 revision 66547) [x86_64-darwin19]
Rails version - Rails 5.2.4.2
Devise version - 4.7.1
Turbolinks - Yes
Try replacing your form_for with form_with in your sessions/new.html.erb. I have a similar problem (Rails 6) and it seems to be ok now.
<%= form_with(model: resource, scope: resource_name, url: session_path(resource_name)) do |f| %>
Additionally, I uncommented the Turbolinks section in config/initializers/devise.rb:
ActiveSupport.on_load(:devise_failure_app) do
include Turbolinks::Controller
end
This sounds like an issue with your frontend (more specifically Turbolinks) rather than the backend. As your log shows, the redirect actually happens from an HTTP standpoint.
Since I haven't run into this issue myself (mainly because I haven't used Turbolinks much in more complex apps), I can only point you to a few resources that describe issues similar to yours, namely:
Getting turbolinks wrapper to work with Ruby on Rails Devise
https://www.oarod.com/2017/01/29/turbolinks-with-devise/
I hope one of these two helps.
If not, feel free to share some frontend code – like I said, I think the issue is on the frontend, not the backend.
The first thing I would try is to do a return redirect_to :
def after_sign_in_path_for(resource)
set_flash_message! :alert, :warn_pwned if resource.respond_to?(:pwned?) && resource.pwned?
return redirect_to set_root
# super
end
I have an application with a log out link: <%= link_to('Logout', destroy_user_session_path, method: :delete) %>
Upon clicking the link, I get the following in my dev server logs:
Started DELETE "/users/sign_out" for 172.30.0.1 at 2019-03-06 14:52:49 +1300
Processing by Users::SessionsController#destroy as HTML
Parameters: {"authenticity_token"=>"JLLEb2GSjGuYx+oBhsAkB0jcP0qZCJEUBvuH5VDmCS9Xbwe/hw085gumBPqJmWTtjyFeW1Io81n32NGxDuKjyQ=="}
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 4 ORDER BY `users`.`id` ASC LIMIT 1
(0.2ms) BEGIN
(0.4ms) COMMIT
Redirected to https://webdev.test:3000/
Completed 302 Found in 28ms (ActiveRecord: 0.9ms)
And the root page then loads again, but the user has not signed out.
I opened up a tab in incognito mode in Chrome and tried logging in and logging out, and it worked fine, so it appears to be something specific to my normal-mode browser. I've tried restarting the browser and it doesn't make a difference.
The user account I'm signed in as in Devise is not increasing its sign-in count each time I do this, nor is the updated_at timestamp changing.
I then put byebug in my root page controller method and ran the following:
1: class HomeController < ApplicationController
2: def index
3: byebug
=> 4: # Omitted for brevity, nothing which touches the current_user object
5: end
6: end
(byebug) Devise.sign_out_all_scopes
true
(byebug) sign_out
(0.8ms) BEGIN
(0.4ms) COMMIT
true
(byebug) continue
And confirmed after that, the user still was not signed out.
Restarting the Rails application and trying all the above again resulted in the same outcome, I still can't sign that user out.
Has anyone seen this before and have any ideas on what's getting stuck and how I can sign out?
Edit
As requested by a commenter, the routes relating to sign_out:
$ rails routes | grep sign_out
destroy_user_session DELETE /users/sign_out(.:format) users/sessions#destroy
$
The output of rails routes | grep destroy_user_session are identical to the above as well, so it shows there's not a named route directing requests to a different controller action.
And the controller at app/controllers/users/sessions_controller.rb (which only overrides the create method, not the destroy method)
class Users::SessionsController < Devise::SessionsController
def create
# Omitted for brevity
end
end
I tried and created user controller to check and seem everything is good. I have only one strange problem, which I am not sure why it is changed. It is about SQL Query. Your response is getting following query.
SELECT `users`.* FROM `users` WHERE `users`.`id` = 4 ORDER BY `users`.`id` ASC LIMIT 1
How come it has 4 id as hard coded, normally it should be prepared statement like following
SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 4], ["LIMIT", 1]]
So to investigate I will try to use different users to see to login and logout and check if ID is changing or not. If it is not changing then I will investigate where this ID is coming from and why it is hard coded.
Changing to a button instead of link fixed this issue for me <%= button_to 'Exit', destroy_user_session_path, method: :delete %>
I am using the active admin gem into my new project with Ruby 2.5.1p57 and Rails 5.2.1. All are good. But, I am facing the issue with open new resource link or update the resource. Even, If I add permit_params, same issue.
Started GET "/admin/admin_users/new" for 127.0.0.1 at 2018-10-04 20:59:08 +0530
Processing by Admin::AdminUsersController#new as HTML
AdminUser Load (0.5ms) SELECT `admin_users`.* FROM `admin_users` WHERE `admin_users`.`id` = 1 ORDER BY `admin_users`.`id` ASC LIMIT 1
↳ /home/vivek/.rvm/gems/ruby-2.5.1#regroup2/bundler/gems/activeadmin-
c301ab126b3f/lib/active_admin/base_controller.rb:39
Completed 500 Internal Server Error in 3ms (ActiveRecord: 0.5ms)
ArgumentError (wrong number of arguments (given 2, expected 0..1)):
But finally, Fixed the issue by adding below line code to the following
file:
config/initializers/active_admin.rb
def resource_params
[(params[resource_request_name] || params[resource_instance_name]).try(:permit!) || {}]
end
Not sure. Is this correct way to do.
I concede that this is more of a nuisance in development and will be less troublesome in production, but even in production, I don't want devise to be authenticating or adding any overhead whatsoever to /assets requests.
In development, we see a slew of the following (currently about 30 for each of our asset files):
Started GET "/assets/application.js?body=1" for 127.0.0.1 at 2015-09-01 11:53:40 -0500
AfCore::User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 8 ORDER BY `users`.`id` ASC LIMIT 1
I looked and couldn't find any options related to skipping assets, and I don't see where we explicitly added them unless something like protect_from_forgery with: :exception is causing this.
How can we have devise skip all asset requests?
I happen to have access to the source code and it is related to a rack component. Calling warden.user in a rack component is request based and will query for the user for each request. Here is the code used to diagnose:
puts 'before warden.user'
if warden.presence && warden.user.presence
security_context.user = warden.user
end
puts 'after warden.user'
and the console output:
before warden.user
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 3 ORDER BY `users`.`id` ASC LIMIT 1
after warden.user
*****EDIT*****
This can be skipped with:
def call(rack_env)
if rack_env['PATH_INFO'] =~ /^\/assets/
# avoid retrieving the session's user for unnecessary calls - assets/validators
#app.call(rack_env)
else
...
# warden.user stuff
...
#app.call(rack_env)
end
Environment:
Rails: 3.2.12
Ruby: ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-linux]
In my routes.rb, I have:
match '/attendance', to: "attendance#attendance_dashboard"
match '/check_in', to: "attendance#check_in"
In my attendance_controller.rb, I have:
def attendance_dashboard
#registered_and_not_checked_in = get_registered_and_not_checked_in()
end
def check_in
logger.info("Email: #{params["party"]["email"]}")
redirect_to attendance_url
end
When I do to myapp/attendance, it behaves like it should and displays a table with the last field in every row being a link to the attendance controller's check_in action and the params include the hash Party.
When I click on the link, I 404. Specifically, here's what the test.log says (the logger info is to make sure I am not bombing up until the redirect):
Processing by AttendanceController#check_in as HTML
Parameters: {"party"=>{"email"=>"rrrrr.rrr#gmail.com", "event_id"=>"3", "first"=>"Rrr", "last"=>"Rrrrr", "payment"=>"0.0", "transaction_id"=>""}}
[1m[35mBlogPost Load (0.4ms)[0m SELECT `blog_posts`.* FROM `blog_posts`
[1m[36mUser Load (0.4ms)[0m [1mSELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1[0m
Email: rrrrr.rrr#gmail.com
Completed 404 Not Found in 5ms
I also tried the following redirect syntax:
redirect_to attendance_path
What am I missing?
Routes:
This is the output of rake route:
/attendance(.:format) attendance#attendance_dashboard
check_in /check_in(.:format) attendance#check_in
Note that unlike check_in, there is no "path" even though the syntax in routes.rb is the same
You should have this in your routes file:
match '/attendance', to: "attendance#attendance_dashboard", :as => :attendance
match '/check_in', to: "attendance#check_in", :as => :check_in