I am writing integration test for my application. For the following test, I am getting
undefined method 'body' for nil:Nilclass
My RSpec code:
it "should not make a new user" do
visit signup_path
fill_in "Name", :with => ""
fill_in "Email", :with => ""
fill_in "Password", :with => ""
fill_in "Confirmation", :with => ""
click_button "Sign up"
response.should render_template('users/new')
response.should have_selector("div#error_explanation")
end
Controller:
class UsersController < ApplicationController
def new
#user = User.new
#title = "Sign Up"
end
def show
#user = User.find(params[:id])
#title = #user.name
end
def create
#user = User.new(user_params)
if #user.save
# Handle a successful save.
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
#title = "Sign Up"
render 'new'
end
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
test.log:
[1m[36mActiveRecord::SchemaMigration Load (0.0ms)[0m [1mSELECT "schema_migrations".* FROM "schema_migrations"[0m [1m[35m (0.0ms)[0m begin transaction
Started GET "/signup" for 127.0.0.1 at 2015-05-06 19:22:35 +0530
Processing by UsersController#new as HTML
Rendered shared/_error_messages.html.erb (46.8ms)
Rendered users/new.html.erb within layouts/application (93.6ms)
Rendered layouts/_stylesheets.html.erb (15.6ms)
Rendered layouts/_header.html.erb (0.0ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 203ms (Views: 140.4ms | ActiveRecord: 0.0ms)
Started POST "/users" for 127.0.0.1 at 2015-05-06 19:22:36 +0530
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "user"=>{"name"=>"", "email"=>"", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up"}
[1m[36m (0.0ms)[0m [1mSAVEPOINT active_record_1[0m
[1m[35mUser Exists (0.0ms)[0m SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('') LIMIT 1
[1m[36m (0.0ms)[0m [1mROLLBACK TO SAVEPOINT active_record_1[0m
Rendered shared/_error_messages.html.erb (0.0ms)
Rendered users/new.html.erb within layouts/application (0.0ms)
Rendered layouts/_stylesheets.html.erb (0.0ms)
Rendered layouts/_header.html.erb (15.6ms)
Rendered layouts/_footer.html.erb (0.0ms)
Completed 200 OK in 47ms (Views: 15.6ms | ActiveRecord: 0.0ms)
[1m[35m (0.0ms)[0m rollback transaction
Error:
5 errors prohibited this user from being saved:
There were problems with the following fields:
Name can't be blank
Email can't be blank
Email is invalid
Password can't be blank
Password is too short (minimum is 6 characters)
What is missing/wrong in this code?
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
Im having a weird issue trying to force my users to change their passwords on first login.
My server output is telling me it completed the patch successfully, however when I go to log back into the app its still the old password? I'll post output below.
But first here is my code to make this happen:
#application_controller.rb
# Force PW Change On 1st Login
def after_sign_in_path_for(resource)
if current_user.sign_in_count == 1
edit_passwords_path
else
authenticated_root_path
end
end
#passwords_controller.rb
def edit
#user = current_user
end
def update
if current_user.update_without_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end
private
def user_params
params.require(:user).permit(:password, :password_confirmation)
end
#passwords form_for
<%= form_for current_user, url: passwords_path do |f| %>
password:<br />
<%= f.password_field :password %><br />
password_confirmation:<br />
<%= f.password_field :password_confirmation %><br />
<br />
<%= f.submit %>
<% end %>
#routes.rb
resource :passwords
The force password is doing everything it is supposed to except actually saving the new passwords.
my server output:
Started PATCH "/passwords" for ::1 at 2016-09-07 02:23:43 -0600
Processing by PasswordsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"zUOrOdquBht6uwvjvBkPj2yaO0dCgL+3XGhKo0YV1+W/4rEEiiIRHwwOzRCqvSVeVkAO0M7c73ogcmgNQDq/DQ==", "user"=>{"password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Update User"}
User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
(0.1ms) BEGIN
(0.1ms) COMMIT
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 0.7ms)
Started GET "/" for ::1 at 2016-09-07 02:23:43 -0600
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 1], ["LIMIT", 1]]
Processing by WelcomeController#index as HTML
Rendering welcome/index.html.erb within layouts/application
Rendered welcome/index.html.erb within layouts/application (0.4ms)
Rendered layouts/navigation/_unassigned.html.erb (0.5ms)
Rendered layouts/messages/_flash_msg.html.erb (0.5ms)
Completed 200 OK in 56ms (Views: 54.9ms | ActiveRecord: 0.0ms)
In PasswordsController#Update change update_without_password to update_with_password:
def update
if current_user.update_with_password(user_params)
flash[:notice] = "Password updated successfully."
redirect_to authenticated_root_path
else
flash[:alert] = "There was a problem, please try again."
render :edit
end
end
I'm working through the railstutorial.org and am on chapter 7. When I add a new user the controller saves the user to the db then hangs up on the statement redirect_to #user then about 2 minutes later returns the url /users claiming the user already exists. What it seems like it's doing is successfully executing the create controller, saving the user, hanging up on the redirect_to call, then calling the create action with errors. Here's my code, Thanks in advance for any help
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
#flash[:success] = "Welcome to the Sample App!"
#render 'show'
redirect_to user_url(#user.id)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
end
and the routes.rb
SampleApp::Application.routes.draw do
match '/signup', to: 'users#new', via: 'get'
resources :users
root 'static_pages#home'
#match '/create', to: 'user#show', via: 'post'
match '/help', to: 'static_pages#help', via: 'get'
match '/about', to: 'static_pages#about', via: 'get'
match '/contact', to: 'static_pages#contact', via: 'get'
EDIT:
So I pasted the output of the development log below. I guess the good news is it does generate an appropriate redirect at first (the redirect Redirected to https://rails_chp3-c9-jd8001.c9.io/users/26 is what I would expect it to do... so that's good). Unfortunately the page never renders and it reloads the /user url with the POST data two minutes later. I also removed the status :see_other and return (current code updated above)
Started POST "/users" for 64.125.248.3 at 2014-09-23 01:36:02 +0000
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IXfkamhDHYRBHQPdMfVyp7/0zXyTONWCMfk9vO+ljHY=", "user"=>{"name"=>"aus8", "email"=>"aus8#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create my account"}
[1m[35m (0.2ms)[0m begin transaction
[1m[36mUser Exists (0.3ms)[0m [1mSELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('aus8#gmail.com') LIMIT 1[0m
Binary data inserted for `string` type on column `password_digest`
[1m[35mSQL (15.3ms)[0m INSERT INTO "users" ("created_at", "email", "name", "password_digest", "updated_at") VALUES (?, ?, ?, ?, ?) [["created_at", Tue, 23 Sep 2014 01:36:03 UTC +00:00], ["email", "aus8#gmail.com"], ["name", "aus8"], ["password_digest", "$2a$10$yYOz6cxU.mqjGlhl7Q743O0kOJJX930RmFaA1rsHjGCqz71HBIUi6"], ["updated_at", Tue, 23 Sep 2014 01:36:03 UTC +00:00]]
[1m[36m (51.8ms)[0m [1mcommit transaction[0m
Redirected to https://rails_chp3-c9-jd8001.c9.io/users/26
Completed 302 Found in 148ms (ActiveRecord: 67.7ms)
Started POST "/users" for 64.125.248.3 at 2014-09-23 01:38:03 +0000
Processing by UsersController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"IXfkamhDHYRBHQPdMfVyp7/0zXyTONWCMfk9vO+ljHY=", "user"=>{"name"=>"aus8", "email"=>"aus8#gmail.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Create my account"}
[1m[35m (0.1ms)[0m begin transaction
[1m[36mUser Exists (0.3ms)[0m [1mSELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('aus8#gmail.com') LIMIT 1[0m
[1m[35m (0.1ms)[0m rollback transaction
Rendered shared/_error_messages.html.erb (0.6ms)
Rendered users/new.html.erb within layouts/application (5.0ms)
Rendered layouts/_shim.html.erb (0.0ms)
Rendered layouts/_header.html.erb (0.4ms)
Rendered layouts/_footer.html.erb (0.2ms)
Completed 200 OK in 100ms (Views: 25.2ms | ActiveRecord: 0.5ms)
I would start by removing
status: :see_other and return
from your redirect call. Also, try looking at your logs to see if it gives you any idea.
Try changing your create method to redirect to #user rather than user_url(#user.id)
#user.id , is most likely the integer user number.
def create
#user = User.new(user_params)
if #user.save
#flash[:success] = "Welcome to the Sample App!"
#render 'show'
redirect_to #user
else
render 'new'
end
end
I've been working with the acts_as_commentable_with_threading gem and I can't get the comments to save.
My controller:
class CommentsController < ApplicationController
def create
#comment_hash = params[:comment]
#obj = #comment_hash[:commentable_type].constantize.find(#comment_hash[:commentable_id])
# Not implemented: check to see whether the user has permission to create a comment on this object
#comment = Comment.build_from(#obj, current_user, #comment_hash[:body])
if #comment.save
flash[:notice] = "New comment saved!!!!!"
redirect_to status_path(#obj)
#redirect_to profiles_path(current_user)
else
flash[:alert] = "didn't save"
redirect_to status_path(#obj)
end
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def comment_params
params.require(:comment,:commentable_id,:commentable_type, :user_id, :body)
end
end
When I check the development log I can see that the values in the hash are all populated and I can see the transaction start the save, but it is immediately rolled back.
Started POST "/comments" for 127.0.0.1 at 2014-01-30 10:47:54 +0100
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"ojRIz0hj0m8BL613Q9W4DHkYNZqO8eeMvR2gEM6Qhp8=", "comment"=> {"body"=>"test comment", "commentable_id"=>"52", "commentable_type"=>"Status"}, "commit"=>"Submit"}
[1m[35mStatus Load (0.1ms)[0m SELECT "statuses".* FROM "statuses" WHERE "statuses"."id" = ? ORDER BY created_at DESC LIMIT 1 [["id", "52"]]
[1m[36mUser Load (0.3ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1[0m
[1m[35m (0.1ms)[0m begin transaction
[1m[36m (0.1ms)[0m [1mrollback transaction[0m
Redirected to http://localhost:3000/statuses/52
Completed 302 Found in 5ms (ActiveRecord: 0.6ms)