Rails 3.1 postgresql shooting blanks into db - ruby-on-rails-3

I'm using postgresql in development for the first time and have successfully installed the binary onto my 10.6 machine. I've created a Rails superuser, createdb => 'vitae_development' with this user. It shows up in $pqsl => '/du', but when I key in /dt, I get 'no relations'.
My pg gem is pg-0.12.0
In rails 3.10 console, I enter: User.create!(:name => "Sam", :email => "sam#email.me")
The resulting output is:
INSERT INTO "users" ("created_at", "email", "name", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id" [["created_at", Wed, 21 Dec 2011 19:40:13 UTC +00:00], ["email", nil], ["name", nil], ["updated_at", Wed, 21 Dec 2011 19:40:13 UTC +00:00]]
That appears to be a bunch of blanks. I've searched the googles but must have missed the right search terms.
pgAdmin3 seems to show the tables in place, as best as I can determine, but with no data that I can find.
This is the relevant snippet from my database.yml:
development:
adapter: postgresql
database: vitae_development
username: rails
password:
pool: 5
timeout: 5000
For completeness, here's the whole user.rb:
class User < ActiveRecord::Base
attr_accessor :name, :email
email_regex = /\A[\w+\-.]+#[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_insensitive => false }
end
What am I overlooking? I've done rake db:migrate.

Did you perhaps override the email or email= methods or put attr_accessor :email in your User.rb file?
EDIT:
Take out line 2 where it says attr_accessor :name, :email. attr_accessor in the context of rails is for object variables that won't be saved to the database.

Try eliminating the formatting validation on email...if it works I'd take a deeper look at email_regex

Related

Rails nil value when saving to database

I am trying to implement a user authentication system inside rails, this is my model:
class User < ActiveRecord::Base
attr_accessible :id, :email, :name, :password, :created_at, :updated_at
has_secure_password
before_save { email.downcase! }
validates :email, presence: true, :uniqueness => { :case_senstive => false }
validates :name, presence: true
validates :password, presence: true, length: { minimum: 6 }
end
Running in the console i can read the User table successfully, then when i try to create a record:
User.new(:name => "A", :email => "a#a.a", :password => "password")
running valid on it retrurns true, but when saving the record, i get error:
users.password may not be NULL
Extracting the password out of the hash works fine.
What is the problem?
Thanks
Where are you setting :password_confirmation? The example in the docs suggests you need it.
http://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html
Main problem is in has_secure_password. If you are using that you should have string field :password_digest (it's where your encrypted password will be saved). And you need delete field :password and your validator of presence for that too. After add gem 'bcrypt-ruby', '~> 3.0.0' .
And now that should work
user = User.new(:name => "A", :email => "a#a.a",
:password => "password", :password_confirmation => "password")
But better use great gem https://github.com/plataformatec/devise . It has everything you need.
NEW ADDED
you should have attr_accessible for :password_confirmation too and that field should be used in your form.
more info about has_secure_password

rails 3.0 is triggering validation on create for a validation that was supposed to be update only

we are upgrading from rails 2.3 to rails 3 and we have some validation on a model like:
validates_length_of :corporate_type, :in => 1..255, :allow_blank => false, :on => :update, :if => Proc.new { |rra| rra.show_corporate_type? }
In rails 2.3 this only gets called on update, but in rails 3, it seems to be called on create, which breaks some stuff downstream... Can someone explain why this is getting called on create?
Here is the stack:
app/models/rra_agreement.rb:11:in `block in <class:RRAAgreement>'
app/models/foo_application_delegate.rb:29:in `create_application'
Line 28 and 29 are:
rra = RRAAgreement.new()
rra.save
line 11 is the validation line above
thanks
Joel
I would try do the following using :new_record?
validates :corporate_type, :unless => :new_record?
new_records? returns true if it is being just created, else false.
The syntax is changed for rails 3, try this to call only on update,
validates :corporate_type,:length => {:on => :update, :min => 1, :max => 20 }
Well I have a work around, its ugly, but it seems to at least let us move forward:
validates_length_of :corporate_type, :in => 1..255, :allow_blank => false, :on => :update, :if => Proc.new { |rra| return false if rra.id==nil;rra.show_corporate_type? }
This makes it just false if the id is not there,it should be there on update.

Rails validators discrepancy between presence and format

I have a model that takes an email address, but I do not want to require it for instance creation. I tried the following:
validates :email, :presence => false, :format => { :with => email_regex }
But this fails my test suite, the format regex apparently makes the presence of the email attribute required.
I thought it might be possible with a before_save method: is it possible to reject saving the object in a before_save method? Is there a better, "Rails way" of doing this?
You can use :allow_blank (or :allow_nil):
validates :email, :allow_blank => true, :format => { :with => email_regex }

Rails validation error email is too short, email is invalid

In attempting to seed my database I ran into a validation error on my User model's email attribute. The error:
Validation failed: Email is too short (minimum is 5 characters), Email is invalid
The thing is, my email is xxxxxxxx#gmail.com. I have five characters. Sorry for the beginner question but I don't know what is going on. I recently followed Railscasts to reset a User's password, and enable CanCan. I'm not sure if CanCan would affect anything, but prior to exploring that new functionality I've been able to fully seed my database without problems. I've pasted in some of my code below. I'm running Rails 3.0.5 and Ruby 1.9.2.
An example of how I create a User in my seed file:
me = User.create(:email => 'me#gmail.com', :password => 'test', :profile => my_profile)
User.rb model:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :password, :password_confirmation
before_save :encrypt_new_password
before_create { generate_token(:auth_token) }
before_validation :downcase_email
has_one :profile, :dependent => :destroy
accepts_nested_attributes_for :profile
validates :email, :uniqueness => true,
:length => { :within => 5..50 },
:format => { :with => /^[^#][\w.-]+#[\w.-]+[.][a-z]{2,4}$/i }
validates :password, :confirmation => true,
:length => { :within => 4..20 },
:presence => true,
:if => :password_required?
Add :email to attr_accessible to allow mass assignment on it. Without that the email field will not even be set so validation will fail.

confused about how to use bcrypt-ruby

I am implementing a validation scheme and am using the bcrypt-ruby gem.
require 'bcrypt'
class User < ActiveRecord::Base
include BCrypt
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
validates :password, :presence => true, :on => :create,
:confirmation => true,
:length => {:within => 6..12}
before_save :encrypt_password
def has_password?(submitted_password)
self.encrypted_password == submitted_password # this calls a method in bcrypt
# File lib/bcrypt.rb, line 171
# def ==(secret)
# super(BCrypt::Engine.hash_secret(secret, #salt))
# end
end
private
def encrypt_password
self.encrypted_password = Password.create(password, :cost => 5)
end
end
Now in the console I create a new user
>> user = User.create!(:name => "test", :email => "test#test.com", :password => "foobar", :password_confirmation => "foobar")
=> #<User id: 1, name: "test", email: "test#test.com", created_at: "2011-06-23 05:00:00", updated_at: "2011-06-23 05:00:00", encrypted_password: "$2a$10$I7Wy8NDMeVcNgOsE3J/ZyubiNAESyxA7Z49H4p1x5xxH...">
And if I check if the password is valid I do the following:
>> user.has_password?("foobar")
=> true
but if I get the user from the database it fails:
user = User.find(1)
user.has_password?("foobar")
=> false
Why does that happen and how can I implement bcrypt to make this work?
Thank you in advance.
My guess would be that since encrypted_password is stored in the database as a string and not a BCrypt::Password, you're not calling into BCrypt's ==, but rather String's ==. You have to instantiate an instance of the Password around the string hash value. That would be where I'd look.
As described over here you have to use the password class of Bcrypt to utilize the ==
def has_password?(submitted_password)
Bcrypt::Password.new(self.encrypted_password) == submitted_password
end