User.save coming back as: User Exists => False - ruby-on-rails

I created a user and then went user.save and got this => false message... I see it says "user exists" but when I go users = User.all theres only 1 user I created a little while back that appears. So why is it saying this user exists?
irb(main):003:0> user = User.new(:screen_name => "jeff holmes", :email => "jeffholmes#gmail.com", :password => "123456")
/Users/coreyholmes/RubymineProjects/worklink/app/models/user.rb:22: warning: regular expression has ']' without escape: /\A[A-Z0-9._%-]+#(A-Z0-9-]+\.)+[A-Z]{2,4}\z/
=> #<User id: nil, screen_name: "jeff holmes", email: "jeffholmes#gmail.com", password: "123456">
irb(main):004:0> user.save
(0.2ms) BEGIN
User Exists (0.3ms) SELECT 1 AS one FROM `users` WHERE `users`.`screen_name` = BINARY 'jeff holmes' LIMIT 1
User Exists (0.2ms) SELECT 1 AS one FROM `users` WHERE `users`.`email` = BINARY 'jeffholmes#gmail.com' LIMIT 1
/Users/coreyholmes/.rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/activemodel-4.2.1/lib/active_model/validations/format.rb:8: warning: regular expression has ']' without escape: /\A[A-Z0-9._%-]+#(A-Z0-9-]+\.)+[A-Z]{2,4}\z/
(0.1ms) ROLLBACK
=> false
UPDATE
Here is the validation code
class User < ActiveRecord::Base
# Max and min lengths for all fields
SCREEN_NAME_MIN_LENGTH = 4
SCREEN_NAME_MAX_LENGTH = 20
PASSWORD_MIN_LENGTH = 4
PASSWORD_MAX_LENGTH = 20
EMAIL_MAX_LENGTH = 50
SCREEN_NAME_RANGE = SCREEN_NAME_MIN_LENGTH...SCREEN_NAME_MAX_LENGTH
PASSWORD_RANGE = PASSWORD_MIN_LENGTH...PASSWORD_MAX_LENGTH
validates_uniqueness_of :screen_name, :email
validates_length_of :screen_name, :within => SCREEN_NAME_RANGE
validates_length_of :password, :within => PASSWORD_RANGE
validates_length_of :email, :maximum => EMAIL_MAX_LENGTH
validates_format_of :screen_name,
:with => /\A[A-Z0-9_]*\z/,
:message => 'must contain only letters, ' + 'numbers, and underscores'
validates_format_of :email,
:with => /\A[A-Z0-9._%-]+#(A-Z0-9-+\.)+[A-Z]{2,4}\z/,
:message => 'common... enter a real email address'
end

I suspect this is part of the problem:
/\A[A-Z0-9._%-]+#(A-Z0-9-]+\.)+[A-Z]{2,4}\z/
# ↑
# Is this supposed to be "(["?
P.S. This is also a bad regex for validating an email address. For one thing, there are tons of TLDs with more than four characters now.

Related

Rspec presence: true check fails even though it works as intended

I have the following Rspec test with the following output for my User model in a Rails API I'm building:
RSpec.describe User, type: :model do
let(:michael) { User.new(email: "michael#email.com", password: "Password1", password_confirmation: "Password1") }
it 'is not valid without a password' do
michael.password = ''
expect(michael).not_to be_valid, "Expect User to have a Password"
end
end
1) User basic checks is not valid without a password
Failure/Error: expect(michael).not_to be_valid, "Expect User to have a Password"
Expect User to have a Password
# ./spec/models/user_spec.rb:19:in `block (3 levels) in <main>'
However, for some reason this test just fails, even with the following on my User model
class User < ApplicationRecord
has_secure_password
validates :email, presence: true, uniqueness: true
validates :password, presence: true
validates :password,
format: { with: /\A(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9]).{8,}\Z/, message: "Password must be at least 8 characters long, contain at least 1 uppercase and 1 lowercase letter and 1 number" },
confirmation: true,
on: :create
end
The above validation works fine, as you can see here:
➜ rails c
Running via Spring preloader in process 2774
Loading development environment (Rails 6.0.3.1)
irb(main):001:0> new = User.new
irb(main):002:0> new.email = "testing#testing.com"
irb(main):003:0> new.save
(0.2ms) BEGIN
User Exists? (0.6ms) SELECT 1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2 [["email", "testing#testing.com"], ["LIMIT", 1]]
(0.2ms) ROLLBACK
=> false
irb(main):004:0> new.errors
=> #<ActiveModel::Errors:0x00007f743848dfb0 #base=#<User id: nil, email: "testing#testing.com", password_digest: nil, created_at: nil, updated_at: nil, admin: false>, #messages={:password=>["can't be blank", "can't be blank", "Password must be at least 8 characters long, contain at least 1 uppercase and 1 lowercase letter and 1 number"]}, #details={:password=>[{:error=>:blank}, {:error=>:blank}, {:error=>:invalid, :value=>nil}]}>
What exactly am I doing wrong here for this test to fail? It's a painfully simple one, and all the other ones work as expected except for the password test.
First, in your tests password = '' is a valid one because for Ruby, '' is something. You have to add this to your validation:
validates :password, presence: true, allow_blank: false
Also, take a look, your password validation is for on: :create and in your spec you are not creating it.

how can I debug my .save method on rails due it is not saving the information it should?

I am trying to save some information, actually editing one existing, and I created a form like this
%form{ :action => "/users/custom", :method => "post", :controller => "/users", data: {remote: true}}
%input{:type => "text", :name => "name", :class => "text ", :value => " #{#current_user.first_name} #{#current_user.last_name}" }
%input{:type => "text", :name => "age", :class => "text ", :value => " #{#current_user.age}" }
and I have others (weight, and address)... the problem that only one for "mail" with the exact same way of these fields is being persisted on the DB, but the other fields, for example age they get persisted with 0
On my controller I have something like this
#user = User.find(session[:current_user])
#user.email = params[:mail]
#user.weight = params[:weight].to_i
... and so on...
if #user.save
flash[:notice] = 'The User is successfully saved!'
end
any way to fix this? or to know what is wrong?
thanks
EDIT
Started POST "/users/custom" for 192.168.1.21 at 2013-05-08 15:50:04 -0600
Processing by UsersController#custom as JS
Parameters: {"name"=>"name", "mail"=>"NEW MAIL", "sex"=>"1", "weight"=>"180" ... }
User Load (0.1ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
(0.1ms) BEGIN
(0.3ms) UPDATE `users` SET `email` = 'NEW MAIL', `sex` = 0, `ssn` = 0, `updated_at` = '2013-05-08 21:50:04' WHERE `users`.`id` = 1
(1.2ms) COMMIT
editing the name doesnt work, the only thing that works its the email.
When I want to edit them with the scaffolds' default forms, I cant see the field weight and so on, just few, incluiding name (which from here I cant edit either)
My model has some restrictions.
validates :first_name, :format => { :with => /\A[a-zA-Z]+\z/, :message => "Only letters allowed" }, :allow_blank => true
The problem is even if I remove it... keeps inserting 0... any idea?
You can put a debug breakpoint by doing: binding.pry anywhere in your controller action. Be sure to add the Pry gem to your Gemfile like so gem 'pry'.
Then execute your code and the breakpoint should hit in your server window for you to debug the problem.

Rails 3.1. Create one user in console with secure password

I want to create one user (admin) and I want to use console (without user registration model). I use solution from RailsCasts (http://railscasts.com/episodes/270-authentication-in-rails-3-1).
But I have one problem: when I do User.create(..., :password => "pass") in console my password stored in database without encription (like "pass"). And I can't login with my data.
How can I create user from console? :)
Straight from the Rails API
# Schema: User(name:string, password_digest:string)
class User < ActiveRecord::Base
has_secure_password
end
user = User.new(:name => "david", :password => "", :password_confirmation => "nomatch")
user.save # => false, password required
user.password = "mUc3m00RsqyRe"
user.save # => false, confirmation doesn't match
user.password_confirmation = "mUc3m00RsqyRe"
user.save # => true
user.authenticate("notright") # => false
user.authenticate("mUc3m00RsqyRe") # => user
You need to include :password_confirmation => "pass in your hash!
Right, so taking a look at has_secure_password you want to perform BCrypt::Password.create(unencrypted_password) to obtain it. You'll need the bcrypt-ruby gem to do the above.

Devise - changed authentication_keys to :login after upgrade from restful_authentication - invalid email or password error

I recently upgraded my Rails app from restful_authentication to devise, and by default the devise login page worked (authenticating with email). I don't want to authenticate via email though and when I moved authentication on 'login' field on the user model, it no longer works and I get the following error:
Invalid email or password.
Devise.rb
config.authentication_keys = [ :login ]
User.rb
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable, :trackable,
:encryptable, :encryptor => :restful_authentication_sha1
attr_accessible :login, :email, :password, :password_confirmation, :remember_me, :twitter_name, :twitter_id, :atoken, :asecret
new.haml (for session)
= form_tag session_path, :class => 'enter_form' do
%label.form_label_small{:for => "login", :style => "color: #336699"} username
%br/
= text_field_tag 'login', #login, :class => 'input_style_state', :style => 'width: 250px;'
.clear{:style => 'height: 4px'}
%label.form_label_small{:for => "password", :style => "color: #336699"} password
%br/
= password_field_tag 'password', nil, :style => 'width: 250px;'
.clear{:style => 'height: 4px'}
%p{:style => "padding: 0; margin:0;"}
= check_box_tag 'remember_me', '1', #remember_me, :style => 'padding: 0; margin: 0; border: 0'
= label_tag 'remember_me', 'remember me'
.clear{:style => "height: 8px"}
%a.button.submit_form{:href => '/login'}
%span{:style => 'width: 40px'}
login
I've had a similar problem with another project. I imagine if :login was being picked up successfully as the authentication key, that the error message would say 'invalid login or passowrd' rather then 'invalid email or password'
Any ideas on how to hunt this down? My error logs don't say anything. Here's the log:
Started POST "/users/sign_in" for 127.0.0.1 at Thu Nov 10 13:46:13 -0500 2011
Processing by Devise::SessionsController#create as HTML
Parameters: {"authenticity_token"=>"AMole3YOhXPuOQGX27W1Mr7c18XR1Xk9DUF6JvstbZA=", "utf8"=>"✓", "user"=>{"remember_me"=>"0", "login"=>"aressidi", "password"=>"[FILTERED]"}}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`login` = 'aressidi' LIMIT 1
NavAd Load (0.3ms) SELECT `nav_ads`.* FROM `nav_ads`
Completed in 34ms
Processing by Devise::SessionsController#new as HTML
Parameters: {"authenticity_token"=>"AMole3YOhXPuOQGX27W1Mr7c18XR1Xk9DUF6JvstbZA=", "utf8"=>"✓", "user"=>{"remember_me"=>"0", "login"=>"aressidi", "password"=>"[FILTERED]"}}
Devise error messages aren't generated dynamically, so the error message doesn't necessarily indicate that it's looking at the wrong field for authentication. See http://asciicasts.com/episodes/210-customizing-devise
Also take note of which version of ruby you're using. Devise doesn't seem to correctly use it's config.authentication_keys setting with Ruby 1.9.3. It started working immediately once I switched back to Ruby 1.9.2.

Rails is not inputting user data to postgresql

I am having an issue with Rails not inputting values to postgresql. The database itself is connected. When I run db:create:all (snippet from database.yml)
development:
adapter: postgresql
encoding: unicode
database: website_development
username: postgres
password: *******
host: 127.0.0.1
port: 9435
(test: is the same but with database: website_test instead of website_development) all the databases are created for test and development. When I run my db:migration the user table is also created e.g. snippet from migration file "date"_create_user.rb
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.string :username
t.string :email
t.timestamps
end
end
def self.down
drop_table :users
end
end
(I have checked in pgAdmin and found the tables that where created)But when I try to insert data from the console e.g.(this was run in sandbox)
irb(main):001:0> User.create!(:username => "John", :email => "john#example.com)
=> #<User id: 1, username: nil, email: nil, created_at: "2011-04-26 22:00:28", u
pdated_at: "2011-04-26 22:00:28">
here is the sql produced on a different create! I had run
[1m[35mSQL (2.0ms)[0m INSERT INTO "users" ("username", "email", "created_at", "updated_at") VALUES (NULL, NULL, '2011-04-26 20:53:43.363908', '2011-04-26 20:53:43.363908') RETURNING "id"
Any help as to why rails is creating the databases and tables fine but can't find the proper username and email to enter into sql.
P.S. I am running Rspec for my tests and have made several tests regarding the values of username and email not being nil to which all succeed.
......................
Finished in 1.62 seconds
22 examples, 0 failures
Notification failed: 201 - The destination server was not reachable
Notification failed: 201 - The destination server was not reachable
As you can see all Rspec tests are green but it to is having trouble connecting to the postgres server
Thank you in advance for any advice.
Update: added user model snippet
class User < ActiveRecord::Base
attr_accessor :username, :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
username_regex = /\A[\w\d]+\z/i
validates :username, :presence => true,
:format => { :with => username_regex },
:length => { :maximum => 30},
:uniqueness => { :case_sensitive => false }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false }
end
==Answer==
These were my mistakes:
Part 1: By changing attr_accessor to attr_accessible all my tests worked properly, and everything that needed to went to red, this also allowed me to add :email details but not :username details which leads to part 2.
Part 2: For some reason rails didn't like the fact that my table was named :user and my column was named :username. So I tried changing :username to :loginname which fixed the problem entirely.
Thank you everyone for all your help.
To isolate this you may want to construct a unit test to replicate the problem, then repair it as required. At first I suspected it would be a case of protected attributes, but it appears you have made them accessible, which is the correct thing to do.
Calling create! directly is somewhat hazardous as you are not easily able to capture the object that is half-created in the event of an exception. This is because although the exception contains a reference to a model, it is not clear if the User model or some other model caused the exception in the first place without additional digging.
A more reliable approach is this:
def test_create_example
user = User.new(:username => "John", :email => "john#example.com")
assert_equal 'John', user.username
assert_equal 'john#example.com', email
user.save
assert_equal [ ], user.errors.full_messages
assert_equal false, user.new_record?
end
If an error occurs in the validation stream you will see the error listed alongside what should be an empty array. It also checks that the record has been saved by testing that it is no longer a new record as records can be valid but fail to save if a before_save or before_create filter returns false, something that happens by accident quite often.
If you call new and then save you have an opportunity to inspect the newly prepared object before it is saved, as well as after.

Resources