users_controller.rb
class UsersController < ApplicationController
include UsersHelper
def new
#user = User.new
end
def create
if isUsernameTaken?
render 'new'
elsif isEmailTaken?
render 'new'
else
#user = User.new(user_params)
if #user.save
else
render 'new'
end
end
end
private
def user_params
params.require(:user).permit(:username,:email,:password,:password_confirmation)
end
end
users_helper.rb
module UsersHelper
def isUsernameTaken?
!(User.find_by(username: params[:username]).nil?)
end
def isEmailTaken?
!(User.find_by(email: params[:email]).nil?)
end
end
The problem is isUsernameTaken? or isEmailTaken? never gets executed and always the else part gets executed even if I give same username again. Why is this happening?
This is because params[:username] and params[:email] are always blank in your controller. They should be params[:user][:username] or user_params[:username].
Anyway, those kind of checks belongs to the model, not the controller and there already are validators to do exactly what you want:
class User < ActiveRecord::Base
validates :email, :username, uniqueness: true
end
Related
I'm trying to setup active storage to upload an avatar when a new user register.
I have run:
rails active_storage:install
rails db:migrate
It's a simple app without devise.
I have put "has_one_attached" in model/user.rb
class User < ApplicationRecord
before_save { self.username = username.downcase }
has_one_attached :avatar
end
I have put ":avatar" in strong parameters on user controller:
class UsersController < ApplicationController
def new
#user = User.new
end
def edit
#user = User.find(params[:id])
end
def update
#user = User.find(params[:id])
#user.avatar.attach(params[:avatar])
if #user.update(user_params)
flash[:notice] = "Your account information was succesfully updated"
redirect_to user_path
else
render 'edit'
end
end
def create
#user = User.new(user_params)
#user.avatar.attach(params[:avatar])
if #user.save
flash[:notice] = "Welcome to Edx Wallet"
redirect_to user_path(#user)
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:username, :avatar)
end
Finally I have put the following code in my navigation view to use a generic avatar in case no user is logged in
<%= image_tag user_avatar(current_user, 40), class: "lg:ml-4 mt-1 lg:mb-0 mb-1 ml-5 pointer-cursor hover:bg-gray-50"%>
And in my application_helper:
def user_avatar(user, size=40)
if user.avatar.attached?
user.avatar.variant(resize: "#{size}x#{size}!")
else
'https://randomuser.me/api/portraits/women/49.jpg'
end
end
But when trying to display Im getting an error:
Showing
/home/edxco/Documents/Microverse/financial_app/app/views/layouts/_nav.html.erb
where line #48 raised:
undefined method `avatar' for nil:NilClass
> def user_avatar(user, size=40)
> if user.avatar.attached?
> user.avatar.variant(resize: "#{size}x#{size}!")
> else
> 'https://randomuser.me/api/portraits/women/49.jpg'
> end
> end
What I am doing wrong? Could you help me, please?
Your user isn't defined. In your helper method try the instance variable #user that you've set in your controller instead of user.
I am making a basic account setup and to try to learn how the database stuff works. I have been running into this error constantly, and I have no idea how to make it disappear. I have my stuff named as U, so the URL will be easier to type a username like Reddit has it example.com/u/username
The Error is uninitialized constant UController::User_param
It highlights this code: #user = U.new(User_param)
Controller:
class UController < ApplicationController
def index
#users = U.all
end
def show
end
def create
#user = U.new(User_param)
if #user.save
redirect_to :action => 'list'
else
#user = U.all
render :action => 'new'
end
end
def User_param
params.require(:Us).permit(:id, :email, :password, :created_at, :updated_at)
end
def new
#user = U.new
end
def edit
end
end
Routes:
resources :u
U Model:
class U < ActiveRecord::Base
end
In Rails you don't capitalize methods, only constants and classes. change User_param to user_params along with the method and that should work. I made params plural since it is clearer and easier to understand
Also, change the user_param method to this:
def user_params
params.require(:u).permit(:id, :email, :password, :created_at, :updated_at)
end
The .require(:u) doesn't need to be plural as you had it.
I am having a rather difficult problem i want to update the user profile only if they submit the current password.I am not using devise.And another post here at stack overflow didn't really help me.
This is my User controller code:
class UsersController < ApplicationController
def new
#user = User.new
end
def show
#user = User.find(params[:id])
#user_posts = #user.posts if #user
if #user
if #user_posts
render 'show.html'
else
render 'show.html'
end
else
render file: 'public/404.html', status: 404, formats: [:html]
end
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
redirect_to root_path
flash[:notice] = "Successfully Signed up :-)"
else
redirect_to signup_path
flash[:notice] = "You didn't sign up successfully :-("
end
end
def edit
#user = User.find(params[:id])
if current_user.id = #user.id
render 'edit'
else
redirect_to #user
end
end
def update
#user = User.find(params[:id])
if #user.update_attributes(user_params)
flash[:notice] = "Profile updated"
redirect_to #user
else
render 'edit'
end
end
:password == :password_confirmation
private
def user_params
params.require(:user).permit(:user_name, :email, :password, :password_confirmation)
end
end
And this is my user.rb:
class User
has_secure_password
has_many :posts
has_many :comments
def admin?
self.role == 'admin'
end
def moderator?
self.role == 'moderator'
end
end
Please help because I have been working with this for a long time now. And the other solution about this topic here at stack overflow didn't work.
One way is to use virtual attributes
1. The User model
class User < ActiveRecord::Base
attr_accessor :current_password
end
2. The form
add the current_password attribute to the form as a text_field input
3. The UsersController
def update
#user = User.find params[:id]
if #user.authenticate(update_params[:current_password])
# update the user
# maybe check if the data are valid
#user.update(update_params)
else
flash[:warning] = "Please provide your password"
#user.errors.add :current_password, "invalid"
render :edit
end
end
def update_params
params.require(:user).permit(:current_password, :email)
end
First, you have a problem in your edit action:
current_user.id = #user.id
That assigns #user.id to current_user.id - you wanted == to test that it's the correct User. You should put a similar check on update, and probably extract it into a before_action so you can easily apply it anywhere you want to.
To check that the password is present, add it to your form like any other field and then get it out of params to verify it. That would look something like this:
class UsersController < ApplicationController
def update
encrypted = encrypt(params[:password]) # Using whatever your mechanism is
if encrypted == #user.encrypted_password
# Update the user
else
flash[:notice] = 'Password is required to update user information.'
redirect_to edit_user(path(#user))
end
end
end
This is my controller for the app.
private
def app_params
params.require(:login).permit(:name, :surname, :username, :password, :email)
end
def new
#login = Login.new app_params
unless app_params.nil?
#login.save
end
end
def show
#post = Post.find(params[:id])
end
def create
#login = Login.new(params[:login])
if #login.save
flash[:success] = "Saved"
redirect_to root_path
else
render "new"
end
end
Code for the new_login_path is:
<%= form_for Login.new do |f| %>
so on..
The error message it shows is:
undefined method `logins_path' for #<#:0x007fba3824be28>
The logins_path method should be generated automatically by Rails based on the contents of your config/routes.rb file. Do you have a line like this?
resources :logins
After you fix your routing issue, you'll want to move your action methods above the private declaration as in Manoj Monga's answer.
You need to define the action above private. every method you define below private is treated as private method. while the controller actions need to be publicly accessible. So Define the action above the private keyword.
def new
#login = Login.new app_params
unless app_params.nil?
#login.save
end
end
def show
#post = Post.find(params[:id])
end
def create
#login = Login.new(params[:login])
if #login.save
flash[:success] = "Saved"
redirect_to root_path
else
render "new"
end
end
private
def app_params
params.require(:login).permit(:name, :surname, :username, :password, :email)
end
What I am trying to do is to go to user's page after signin/up. On the error page is written that the error is in users_controller. So this is my user controller:
class UsersController < ApplicationController
def show
#user = User.find([:id])
end
def index
end
def new
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
# Handle a successful save.
else
render 'new'
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
end
Your show method should be:
def show
#user = User.find( params[:id] )
end
And not [:id] alone. You're accessing the :id key at the params hash object.