I am seeing the following SQL being used to check that an email address (e.g. joebloggs#joebloggs.com) is unique when a user signs up on my Ruby website:
SELECT `users`.id FROM `users` WHERE (`users`.`email` = BINARY '--- !ruby/object:Mail::Multibyte::Chars \nwrapped_string: joebloggs#joebloggs.com\n') LIMIT 1
This is always resulting in zero rows being returned, so Ruby attempts to create the user in the database. On the attempted record creation in MySQL, it fails because users.email has a unique index on it.
Can anyone tell me why Ruby is generating the SQL statement above? It does this on my live site running in production or development mode. On my development site (running in production or development mode), the following (correct) SQL is generated:
SELECT `users`.id FROM `users` WHERE (`users`.`email` = BINARY 'joebloggs#joebloggs.com') LIMIT 1
For user management, I am using devise with the following setting:
validates_uniqueness_of :email
Thanks in advance for your help.
In your user model you can add email validation to uniqueness as false.
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :confirmable,
# :lockable, :timeoutable and :omniauthable
devise :database_authenticatable,:registerable,
:recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:email]
validate :email, presence: true, uniqueness: false
end
Related
I'm using Devise to manage user model.
Here's the User model, user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
acts_as_voter
has_many :topics
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
Here's the Topics model, topic.rb
class Topic < ActiveRecord::Base
acts_as_voteable
belongs_to :user
end
When I create a post, the user ID is stored in the "user_id" column of Topics. I want to a User profile page, which should display all the posts he has made. In my User profile page view, I have,
<%= Topic.find_by_user_id(#user.id) %>
I have two posts made by the same user,
But when I try fetch all the posts made by the user, the SQL command automatically queries with a LIMIT of 1. Like this,
And because of this, the view is fetching only 1 post made by the user. How do I fetch all the posts?
find_by_attribute will always return only one result. You need to change your code to:
Topic.where(user_id: #user.id)
or even better:
#user.topics
I'm in the process of upgrading a large project from rails 2 to rails 3, as a part of that upgrade I'm replacing a very old restful_athentication with devise.
The problem I'm having is that in the existing users table emails are validated like this.
validates_uniqueness_of :email, :scope => :account_id # No dupes within account
So if I add the index from the migration to add devise to users it WILL fail.
Is there a way that I can use
add_index :users, [:email,:account_id]
And have devise work properly?
I managed to get this working on my own, I added the following to config/initializer/devise.rb
config.authentication_keys = [ :email , :account_id]
I am attempting to create a rails 3.2.13 app where when the user is created a password is auto generated for that user. Right now I am using a before_validate to generate and assign the password to the password and password_confirmation fields on the user object before it is creates but devise still complains that the password is still blank.
What is the best approach to get devise to accept the password that I have generated for my user object? It would be nice to be able to do this without having to overwriting the internal validation if possible.
I don't known what you are doing wrong... Tried quickly here and everything turned out ok.
Here is my model
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
before_validation :set_user_password
def set_user_password
#password = Devise.friendly_token
end
end
I didn't even had to set password_confirmation just password and it saved without errors at the rails console.
The previous solution is awesome. But you can not reset your password. set_user_password should only execute when creating account.
before_validation :set_user_password, :on => :create
def set_user_password
#password = Devise.friendly_token
end
I would like to use the devise option :reconfirmable in my user model, so whenever a user changes his email, he needs to confirm it with a link sent by email.
The big problem is, that the email gets never sent ...
My setup is with devise 2.1.2 is:
user model:
attr_accessible: unconfirmed_email, ...
devise :invitable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable, :omniauthable
in the initilizer devise.rb:
config.reconfirmable = true
in the routes:
devise_for :users
in the form the model field unconfirmed_email gets set properly. I checked this through the console.
The first confirmation email, when a user registers on the page gets send out without problem.
I tried debugging the problem with adding this code to the initializers directory to overwrite the devise methode that gets triggered as a after_update hook:
module Devise::Models::Confirmable
def send_confirmation_instructions
debugger
end
end
it seems like send_confirmation_instructions is never called, since I never get to the debugger.
Do I somehow need to call reconfirmable, or does it gets triggered automatically when setting the model attribute "unconfirmed_email" to a new email address?
Thankfull for any help,
j.
OK, this is embarrassing..
After diving into the Devise code, I figured out that you don't need to set the unconfirmed_email attribute of your user model, but just change the existing email attribute. The attribute unconfirmed_email is just used internally for Devise to store the email address until it's confirmed.
Later version of devise gem explains this in initial migration. Here is "Confirmable" section (note the comment on the last line) from XXX_devise_create_users.rb migration:
## Confirmable
t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email # Only if using reconfirmable
Sorry for bothering, but hopefully this can help somebody having the same problem...
I'm using Devise for authentication with two custom fields added = :organization_id and :username. I also generated a scaffold for the Organization which simply consists of Name.
Currently when users sign up they can type in an Organization ID (integer) and a username (string).
Users belong_to organizations, and organizations has_many users.
Here's what my models look like (I left everything else untouched except for the files inside app/views/devise/registrations to add organization_id and username):
#user.rb
class User < ActiveRecord::Base
belongs_to :organization
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :organization_id, :username
end
#organization.rb
class Organization < ActiveRecord::Base
has_many :users
end
What I would like is for an organization to be automatically created when a user signs up without the user having to specify the organization_id.
Also, ideally the #organization.name would be exactly the same as :username
How would I go about doing this?
I've seen the Railscast on nested model forms but he's creating a question inside the survey form, and questions belong to a survey. I need to do it the other way around (create an organization inside the user form, where users belong to a survey.)
Any help and suggestions would be greatly appreciated..
class User < ActiveRecord::Base
before_create :create_organization
private
def create_organization
self.organization = Organization.create :name => self.username
end
end
The create_organization method will be executed right before the sql query which creates the user. It'll create a new organization and assign it to the user.