I am trying to render show action by passing parameters, but the show page is not being rendered when there are no users signed in. This is my controller:
class QrCodesController < ApplicationController
def show
#user = User.find_by_qr(params[:id])
if #user.nil?
redirect_to root_path
end
end
end
and this is my view:
This is the qr-code page of <%= #user.fname %> <%= #user.lname%>
However, the show page is perfectly rendered when any user is signed in.
The rails server also shows perfectly rendered show action:
Started GET "/qr_codes/9M9JZLiemrNdS_g90mZ14w" for 127.0.0.1 at 2013-08-02 18:29:55 +0545
Processing by QrCodesController#show as HTML
Parameters: {"id"=>"9M9JZLiemrNdS_g90mZ14w"}
User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."qr" = '9M9JZLiemrNdS_g90mZ14w' LIMIT 1
Rendered qr_codes/show.html.erb within layouts/application (0.7ms)
Rendered layouts/_shim.html.erb (0.0ms)
Web Load (0.3ms) SELECT "webs".* FROM "webs" WHERE "webs"."id" = 2 LIMIT 1
Rendered layouts/_header.html.erb (3.2ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 54ms (Views: 52.4ms | ActiveRecord: 0.5ms)
I am using rails 3.2.13, ruby 1.9.3p429 along with devise 3.0.0. The User model was not generated by devise.
Please Help.
EDIT:
This is the link that triggers the show action:
http://localhost:3000/qr_codes/9M9JZLiemrNdS_g90mZ14w
Since #user is equal to # when you print it, it is clearly not equal to nil and the redirection is not happening. You need to either change the code in find_by_qr to return nil if not found, or determine what other way that that method is using to represent not found, and change your conditional to use that.
Try this instead:
#user = User.find_by_qr(params[:id])
if #user
respond_to do |format|
format.html
end
else
redirect_to root_path
end
Related
Trying to figure out why authenication isn't working properly for my code even with gem devise. My login page displays properly but when it comes to logging in with an existing user's info located in the seeds.rb file, it prints out the else statement instead of directing to the home page.
def sign_in
page = User.find_by(email: params[:email])
if page.present? && page.authenticate(params[:password])
session[:user_id] = page.id
redirect_to root_path, notice: "You have successfully logged in"
else
flash[:alert] = "Invalid info"
redirect_to login_path
end
end
I changed the user.authenicate(params[:password]) to page.authenicate(params[:password]) but the same issue was still showing.
Started POST "/login" for ::1 at 2022-11-15 19:30:14 -0600
Processing by PagesController#sign_in as TURBO_STREAM
Parameters: {"authenticity_token"=>"[FILTERED]", "session"=>{"email"=>"hi#email.com", "password"=>"[FILTERED]"}, "commit"=>"Login"}
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."email" IS NULL LIMIT $1 [["LIMIT", 1]]
↳ app/controllers/pages_controller.rb:14:in `sign_in'
Redirected to http://localhost:3000/login
Completed 302 Found in 188ms (ActiveRecord: 2.1ms | Allocations: 8011)
Started GET "/login" for ::1 at 2022-11-15 19:30:14 -0600
Processing by PagesController#login as TURBO_STREAM
Rendering layout layouts/application.html.erb
Rendering pages/login.html.erb within layouts/application
Rendered pages/login.html.erb within layouts/application (Duration: 1.2ms | Allocations: 817)
Rendered shared/_flash.html.erb (Duration: 0.1ms | Allocations: 31)
Rendered layout layouts/application.html.erb (Duration: 80.3ms | Allocations: 6806)
Completed 200 OK in 102ms (Views: 82.3ms | ActiveRecord: 0.0ms | Allocations: 7152)
This is the first clue from your log...
SELECT "users".* FROM "users" WHERE "users"."email" IS NULL
params[:email] is null, because the email parameter is in a form called session, which you can see in the log...
"session"=>{"email"=>"hi#email.com", "password"=>"[FILTERED]"}, "commit"=>"Login"}
so your code needs to use form name to access the email and password parameters properly...
def sign_in
user = User.find_by(email: params[:session][:email])
if user.present? && user.authenticate(params[:session][:password])
session[:user_id] = user.id
redirect_to root_path, notice: "You have successfully logged in"
else
flash[:alert] = "Invalid info"
redirect_to login_path
end
end
The "destroy" method is not working on my site. I created a "delete" link, but when I click it I just get redirected.
Here is the controller with the destroy method:
class PostsController < ApplicationController
def index
#posts = Post.all
end
def show
#post = Post.find(params[:id])
end
def new
#post = Post.new
end
def create
#post = Post.new(post_params)
if #post.save
redirect_to #post
else
render :new, status: :unprocessable_entity
end
end
def edit
#post = Post.find(params[:id])
end
def update
#post = Post.find(params[:id])
if #post.update(post_params)
redirect_to #post
else
render :edit, status: :unprocessable_entity
end
end
def destroy
#post = Post.find(params[:id])
#post.destroy
redirect_to root_path, status: :see_other
end
private
def post_params
params.require(:post).permit(:title, :description, :image, :price)
end
end
Nothing fancy. And here is the link in my posts/show.html.erb view:
<%= link_to 'Delete', root_path,
method: :delete,
data: { confirm: 'Are you sure?' } %>
Doesn't work - I just get redirected to the root path, and the post I tried to delete remains.
I tried removing a post in the rails console, and that did work.
Rails 7.0.4
Ruby 3.1.2
Server output after clicking "delete" link on local site:
Started GET "/posts/3" for ::1 at 2022-10-09 23:59:02 -0400
ActiveRecord::SchemaMigration Pluck (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by PostsController#show as HTML
Parameters: {"id"=>"3"}
Post Load (0.1ms) SELECT "posts".* FROM "posts" WHERE "posts"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
↳ app/controllers/posts_controller.rb:7:in `show'
Rendering layout layouts/application.html.erb
Rendering posts/show.html.erb within layouts/application
ActiveStorage::Attachment Load (0.1ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = ? AND "active_storage_attachments"."record_type" = ? AND "active_storage_attachments"."name" = ? LIMIT ? [["record_id", 3], ["record_type", "Post"], ["name", "image"], ["LIMIT", 1]]
↳ app/views/posts/show.html.erb:11
ActiveStorage::Blob Load (0.1ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]]
↳ app/views/posts/show.html.erb:12
Comment Load (0.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."post_id" = ? [["post_id", 3]]
↳ app/views/posts/show.html.erb:23
Rendered collection of templates [0 times] (Duration: 0.0ms | Allocations: 35)
Rendered comments/_form.html.erb (Duration: 31.1ms | Allocations: 6334)
Rendered posts/show.html.erb within layouts/application (Duration: 142.9ms | Allocations: 31474)
Rendered layout layouts/application.html.erb (Duration: 300.1ms | Allocations: 53293)
Completed 200 OK in 402ms (Views: 312.5ms | ActiveRecord: 2.1ms | Allocations: 66385)
Started GET "/rails/active_storage/disk/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdDVG9JYTJWNVNTSWhiR28xZVRKamJucHhZM0pxZFhaak9YZGxZelY0ZVdwbGREWnlNZ1k2QmtWVU9oQmthWE53YjNOcGRHbHZia2tpWldsdWJHbHVaVHNnWm1sc1pXNWhiV1U5SW1sc1h6RTFPRGg0VGk0ek1qSTNNRGc0TlRZMVh6SmlkWGd1Y0c1bklqc2dabWxzWlc1aGJXVXFQVlZVUmkwNEp5ZHBiRjh4TlRnNGVFNHVNekl5TnpBNE9EVTJOVjh5WW5WNExuQnVad1k3QmxRNkVXTnZiblJsYm5SZmRIbHdaVWtpRG1sdFlXZGxMM0J1WndZN0JsUTZFWE5sY25acFkyVmZibUZ0WlRvS2JHOWpZV3c9IiwiZXhwIjoiMjAyMi0xMC0xMFQwNDowMTo0My45NDVaIiwicHVyIjoiYmxvYl9rZXkifX0=--00b620d927983a0cba2300d10b1e2234b9306a84/il_1588xN.3227088565_2bux.png" for ::1 at 2022-10-09 23:59:03 -0400
Processing by ActiveStorage::DiskController#show as PNG
Parameters: {"encoded_key"=>"[FILTERED]", "filename"=>"il_1588xN.3227088565_2bux"}
Completed 304 Not Modified in 7ms (ActiveRecord: 0.0ms | Allocations: 559)
Looks like you have an issue with Turbo or Rails UJS.
These should really work and send a DELETE request via javascript:
# Turbo
link_to "delete", #post, data: { turbo_method: :delete }
# Rails UJS
link_to "delete", #post, method: :delete
If your javascript is broken than data and method attributes are ignored and you're just clicking a link to show #post, which is what's happening in the log.
On the other hand:
data-turbo-method changes the link request type from the default GET.
Ideally, non-GET requests should be triggered with forms, but
data-turbo-method might be useful where a form is not possible.
https://turbo.hotwired.dev/reference/attributes
To trigger a DELETE request with a form you can use button_to, which creates a little form and rails correctly handles routing to destroy action:
button_to "Delete", #post, method: :delete
https://api.rubyonrails.org/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to
I tried to learn about presenter and did the following classes
User model with id, first_name, last_name, email
user_controller with the following methods
def index
#users = User.all
render_user_json #users
end
def show
#user = User.find_by_id(params[:id])
if #user.nil?
render json: { message: 'User can not be found' }, status: 404
return
end
render_user_json #user
end
def render_user_json(user)
render json: ::Presenters::User::UserPresenter.new(user).generate
end
UserPresenter class
module Presenters
module User
class UserPresenter
attr_reader :user
def initialize(user)
#user = user
end
def generate
{
id: #user.id,
first_name: #user.first_name,
last_name: #user.last_name,
email: #user.email
}
end
end
end
end
When I go to localhost:3000/users/id it works well
but when I go to localhost:3000/users I get the following error
NoMethodError (undefined method `id' for #<User::ActiveRecord_Relation:0x00007f9952ac4930>
Did you mean? ids):
lib/presenters/user/user_presenter.rb:14:in `generate'
app/controllers/users_controller.rb:49:in `render_user_json'
app/controllers/users_controller.rb:9:in `index'
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_source.erb (4.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/actionpack-4.2.11/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (108.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_markup.html.erb (0.4ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.3ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.4ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/console.js.erb within layouts/javascript (91.6ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/main.js.erb within layouts/javascript (0.7ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.8ms)
Rendered /Users/noammansur/.rvm/gems/ruby-2.3.8/gems/web-console-2.3.0/lib/web_console/templates/index.html.erb (210.6ms)
It seems like it doesn't passed as single users
Rather than this:
render_user_json #users
Either make another method render_users_json (note the plural users) or just call the render from the index method directly like this:
# inside index method
render json: users.map do |user|
::Presenters::User::UserPresenter.new(user).generate
end
I'm using rails_admin and I have overrided delete action with adding some line of code:
if request.get? # DELETE
respond_to do |format|
format.html { render #action.template_name }
format.js { render #action.template_name, layout: false }
end
elsif request.delete? # DESTROY
redirect_path = nil
# puts 'CUSTOM DELETE'
# This code to assign current user that will delete following object.
# History tracker can not assign current_user by itself.
if #object.has_attribute?(:updater_id)
#object.updater = _current_user
#object.save
end
#auditing_adapter && #auditing_adapter.delete_object(#object, #abstract_model, _current_user)
if #object.destroy
flash[:success] = t('admin.flash.successful', name: #model_config.label, action: t('admin.actions.delete.done'))
redirect_path = index_path
else
flash[:error] = t('admin.flash.error', name: #model_config.label, action: t('admin.actions.delete.done'))
redirect_path = back_or_index
end
redirect_to redirect_path
end
When the delete action is called it throws:
undefined method `nil' for #<Admin:0x00000011ead6f0>
Yes that is strange. I always get undefined methods for nilClasses but this. This is nil for defined object. This happens on #object.updater - _current_user line
#object is model that will be destroyed. _current_user is logged in Admin model.
Why this error is happening?
The models I use are: Category, SubCategory, Sub2Category and Admin.
Category has_many SubCategory, SubCategory has_many Sub2Category. Admin is updater and _current_user.
This error happened when I try to delete Sub2Category via rails_admin.
Backtrace:
NoMethodError (undefined method `nil' for #<Admin:0x00000013b9b960>):
config/initializers/rails_admin_delete_override.rb:40:in `block (2 levels) in <class:Delete>'
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_source.erb (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/bundler/gems/rails-8b487239e801/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (25.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_markup.html.erb (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_inner_console_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/_prompt_box_markup.html.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/style.css.erb within layouts/inlined_string (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/console.js.erb within layouts/javascript (33.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/main.js.erb within layouts/javascript (1.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/error_page.js.erb within layouts/javascript (0.0ms)
Rendered D:/Ruby21-x64/lib/ruby/gems/2.1.0/gems/web-console-2.2.1/lib/web_console/templates/index.html.erb (84.0ms)
I'm working through a project that is based off the Hartl tutorial. I've setup a user authentication model that works...mostly. Users can sign up, but I'm having a problem with the sign_in process. If a user signs out, it's impossible for them to sign in. I've verified that the database is saving the user's signup information, so the problem is with acknowleding that the user has signed up. I've looked at my logs, but they're unhelpful.
This is what I get:
Started POST "/sessions" for 127.0.0.1 at 2012-04-15 13:56:46 -0500
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"itOIPKPrXlymcBujKMu4Xjwvs6GlD3jteBQJf+/mYEY=", "session"=>{"email"=>"tester3#tester3.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'tester3#tester3.com' LIMIT 1
Rendered sessions/new.html.erb within layouts/application (1.6ms)
Rendered layouts/_stylesheets.html.erb (2.0ms)
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
CACHE (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` IS NULL LIMIT 1
Rendered layouts/_header.html.erb (3.2ms)
Rendered layouts/_footer.html.erb (0.3ms)
Completed 200 OK in 30ms (Views: 16.1ms | ActiveRecord: 2.6ms)
But what I should see is this.
Started POST "/sessions" for 127.0.0.1 at 2012-04-15 12:50:24 -0500
Processing by SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"h/M5VYBaG16sGiGHTWo26GJSU1/TlMNFjQd5TN1VZ3Y=", "session"=>{"email"=>"tester3#tester3.com", "password"=>"[FILTERED]"}, "commit"=>"Sign in"}
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'tester3#tester3.com' LIMIT 1
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`email` = 'tester3#tester3.com' LIMIT 1[0m
Redirected to http://localhost:3000/users/103
Completed 302 Found in 19ms
My questions are:
What's the best way to go about trouble shooting this problem?
What are the "obvious" places that where I should start looking. I'm using the user authentication code found here and I've successfully implemented it in other projets. It's just this one that's giving me trouble.
Here's my authentication code.
module SessionsHelper
def sign_in(user)
cookies.permanent.signed[:remember_token] = [user.id, user.salt]
self.current_user = user
end
def current_user=(user)
#current_user = user
end
def current_user
#current_user ||= user_from_remember_token
end
def signed_in?
current_user.present?
p "user signed_in? method called"
p current_user
end
def sign_out
cookies.delete(:remember_token)
self.current_user = nil
p "user has signed out" #Method does NOT get called
end
def current_user?(user)
user == current_user
end
def authenticate
deny_access unless signed_in?
end
def deny_access
store_location
redirect_to signin_path, :notice => "Please sign in to access this page."
end
def redirect_back_or(default)
redirect_to(session[:return_to] || default)
clear_return_to
end
private
def user_from_remember_token
p "Looking user up from the cookie"
User.authenticate_with_salt(*remember_token)
end
def remember_token
cookies.signed[:remember_token] || [nil, nil]
end
def store_location
session[:return_to] = request.fullpath
end
def clear_return_to
session[:return_to] = nil
end
end
You asked for obvious, so here's obvious...
You could print out the cookie value at the beginning of the action.
You can raise an exception at various points in the action. I like to do this. It's more reliable than the "p" since printing can go through buffered output. I put info that I would print out into the string for the exception. The development mode also spits out helpful information like params.