I want to let the admin user see a particular message after or before or during he creats a new record.
I need either an alert box after he created the new record, or to change the current confirmation message just for the user model, or to add a small text in the form specifying this.
I can't seem to find any of the ways.
Thank you
You need to use "notice:". In my case, after saving new "admin_user", I am checking for "resource". If it is "valid", then "redirect_to" with a "message". ... This always works for me.
ActiveAdmin.register AdminUser do
....
....
permit_params :first_name, :last_name, :email, :password
def create
#admin_user = AdminUser.new( admin_user_params )
#admin_user.save
if resource.valid?
redirect_to collection_url, notice: 'Creation Success'
else
flash[:alert] = 'Creation Failed'
render :new
end
end
private
def admin_user_params
params.require(:admin_user).permit(:id, :first_name, :last_name, :email, :password)
end
end
you can modify the flash message with an after_create callback for that case, something like this
ActiveAdmin.register User do
permit_params :name, :email, :password
after_create do |user|
flash[:notice] = "User has been created with the default password" if user.valid?
end
end
Related
I'm a programming/rails beginner, and have encountered a bug I cannot wrap my head around.
I'm using/learning about the "has_secure_password" method. When I try and create a user in my console with a mismatched password/confirm_password, the console returns false and the error is "Password confirmation doesn't match Password". But, when I try and do the same thing within the UI given the below code (+ a view), it saves just fine! Now, notice that in my "user_params" method, I accidentally forgot to permit ":password_confirmation" which is how I noticed this issue in the first place. With that ":password_confirmation" added, the view throws an error but that's not the point. Why even without this is the new User record being successfully created with a mismatched password and password confirmation, even though it doesn't save in the console?
Here is my User model:
class User < ActiveRecord::Base
has_secure_password
validates :name, presence: true
validates :email, presence: true, format: /\A\S+#\S+\z/, uniqueness: {case_sensitive: false}
validates :password, length: {minimum: 4, allow_blank: true}
end
And my User controller:
class UsersController < ApplicationController
def index
#users = User.all
end
def show
#user = User.find(params[:id])
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
redirect_to #user, notice: "Thanks for signing up!"
else
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password)
end
end
This is happening because the password_confirmation attribute is optional. When it isn't supplied to the model that has_secure_password, the model simply accepts the password.
When your password confirmation attribute isn't whitelisted in your controller via user_params, it isn't being passed to the model at all, which is why mismatches appears not to throw an error. In truth the validation isn't taking place at all.
This works in your console because it creates a user without involving a controller or strong parameter whitelisting.
New to rails, and I think i found my problem but I'm not sure if this is the case
def additional_info
#user = User.find params[:id]
end
def update
#user = User.find(params[:id])
if #user.update(user_addinfo)
render user_path
else
render action: 'additional_info'
end
end
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
def user_addinfo
params.require(:user).permit(:years_business, :years_relationships, :years_careers, :years_lifeoutlook)
end
end
A user suggested that i change the
if #user.update(user_addinfo) to -> if#user.update!(user_addinfo)
the result was an error page saying my password is too short! I went back reread Michael Hartl's guide and rails api on the params. section and i believe this is causing an issue? I've tried changing to
params.permit(:years_business, :years_relationships, :years_careers, :years_lifeoutlook)
only and it still gives a password too short error.... what am i doing wrong? or am i totally misunderstanding the params?
There's probably a length validation in the User model that checks for the length of the given password.
Open the app/models/user.rb file and look for a line like this:
validates :password, length: { minimum: 4 }
or:
validates_length_of :password
I'm using strong parameters in my User controller in my Rails 4 application.
def new
#user = User.new
end
def create
#user = User.new(user_params)
if !#user.save
render :new
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :address_1, :address_2, :city, :state, :zip, :phone, :email, :password, :ssn)
end
I also have validation in the User model.
validates_presence_of :first_name, :last_name
If the user fills out my form to create their account and don't pass the validation, when the controller renders the new action, none of the previously fields the user filled out are populated, the entire form is blank. Am I missing something?
It seems you made new instance variable when validation fails.
You have to use failed instance variable in new form.
if you can't understand my answer please add your code of create action and form view.
I was using Single Table Inheritance and was pre-designating the type of user it would be. Once I removed STI, my fields were appearing in the form no problem.
I have a payment api that takes bank account info and user info. I catch the api response and use ajax to send the infomation into my controller where I try to save the information to my user. When I save I get the error Validation failed: Password can't be blank, Password is invalid: Any ideas?
Bank Controller:
def addbank
#user = current_user
#user.phone_number = params[:phone_number]
#user.birth_year = params[:year]
#user.bank_uri = (params['bank_acct_uri'])
#user.save! # <------- ERROR here!
# Code was removed to be more clear
end
User Controller:
def update
# update user controller has been commented out but the error is still there
end
User Model:
class User < ActiveRecord::Base
attr_accessible :email,:password,:password_confirmation,:phone_number,:birth_year
attr_accessor :password
before_save :encrypt_password
before_save { |user| user.email = email.downcase }
VALID_PASSWORD_REGEX = # some reg-expression
VALID_PHONE = # some reg-expression
validates_confirmation_of :password
validates :password, presence: true, format:{ with: VALID_PASSWORD_REGEX }
validates :phone_number, format: { with: VALID_PHONE }, if: :phone_number
end
Edit: Why is saving user not hitting my update user controller?
If you want to avoid the validation of one particular field (password in your case), but you want to do all the other validations (for example phone number), you can do something like this:
attr_accessor :skip_password
validates :password, presence: true, format:{ with: VALID_PASSWORD_REGEX }, unless: :skip_password
Then, in your controller, you could do:
def addbank
#user = current_user
#user.skip_password = true # We don't want to validate this..
#user.phone_number = params[:phone_number]
#user.birth_year = params[:year]
#user.bank_uri = (params['bank_acct_uri'])
#user.save! # <------- ERROR here!
# Code was removed to be more clear
end
Do this at your own risk ~~
Where are you storing the encrypted password?
If you store it in password then it will fail validation every save because it doesn't equal password_confirmation.
I'd recommend putting the password in a separate field.
#from the User Model
attr_accessor :password, :password_confirmation
validates_presence_of :password, :on => :create
validates_confirmation_of :password
def password=(password)
#password = password
self.password_digest = BCrypt::Password.create(#password, :cost => 14)
end
def authenticate(password)
BCrypt::Password.new(self.password_digest) == password
end
This way the password gets hashed and saved to password_digest and won't trigger a validation error on save.
You can try to save without validation:
#user.save(:validate => false)
UPDATE:
if !#user.valid? && #user.errors[:phone_number].any?
#do not save
else
#user.save(:validate => false)
end
I'll post this as I am about 95% certain this is the cause, but I apologize if I'm off.
I believe the cause of this is because the user's password is indeed blank. If you look at your database, you'll see a column probably called encrypted_password, which is never directly accessed via your model, nor is it ever de-crypted into your accessible password and password_confirmation attributes.
In order to update the user, you will have to enter re-enter the password, or use the save(false) method to (potentially dangerously) bypass validations.
I'll start by telling you how I want my settings page set up.
I want users to be able to change their settings without requiring a password, and that's how it is set up now with this as the user model
validates :password, presence: true, length: { minimum: 6 }, :on => :create
validates :password_confirmation, presence: true, :on => :update, :unless => lambda{ |user| user.password.blank? }
This makes it so user's can change all of their settings without requiring a password (I know some might frown on this). But i want users to be able to change their passwords on the page like so...User clicks Change Password, a modal pops up, and users have to give their current password and then the new password and a confirmation of the new one. (I know how to do modal, i just want to know how do password reset).
Does this make sense?? I believe the way Pinterest does it is a good example (although they use Python I think)
My suggestion is to use a form object:
app/forms/change_password_form.rb
class ChangePasswordForm
extend ActiveModel::Naming
include ActiveModel::Conversion
include ActiveModel::Validations
# Add all validations you need
validates_presence_of :old_password, :password, :password_confirmation
validates_confirmation_of :password
validate :verify_old_password
attr_accessor :old_password, :password, :password_confirmation
def initialize(user)
#user = user
end
def submit(params)
self.old_password = params[:old_pasword]
self.password = params[:password]
self.password_confirmation = params[:password_confirmation]
if valid?
#user.password = password
#user.password_confirmation = password_confirmation
#user.save!
true
else
false
end
end
def verify_old_password
self.errors << "Not valid" if #user.password != password
end
# This method is required
def persisted?
false
end
end
In controller initialize the form object #pass_form = ChangePasswordForm.new(current_user) and use the object in your modal: form_for #pass_form... and add the old_password, password and password_confirmation fields.
And finally, for example, in the update action:
#pass_form = ChangePasswordForm.new(current_user)
if #pass_form.submit(params[:change_password_form])
redirect_to some_path
else
render 'new'
end
I haven't tested this code, but you get the idea. Take a look to this Railscasts.