Edit/Updating user fields in current session in Rails 4.0 - ruby-on-rails

So far I have implemented a simple user with authentication ( user controller and session controller) and I want to go to a MyAccount page using a users#edit route and update, say the email adress of the current user. The problem is that the update function is updating the current view with the email I want to change, but not the database, so when I hit refresh the #user.email object would return to its initial value. Thank you!
class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save
UserMailer.registration_confirmation(#user).deliver
redirect_to log_in_path, :notice => "Signed up!"
else
render "new"
end
end
def edit
#user = current_user
end
def update
respond_to do |format|
if #user.update(user_params)
format.html { redirect_to #user, notice: 'User was successfully updated.' }
else
format.html { render action: "edit" }
end
end
end
private
def set_user
#user = current_user
end
def user_params
params.require(:user).permit(:email, :password, :password_confirmation)
end
end
I have also added the sessions controller I have created.
class SessionsController < ApplicationController
def create
user = User.authenticate(params[:email], params[:password])
if user
session[:user_id] = user.id
redirect_to root_url, :notice => "Logged in"
else
flash.now.alert = "Invalid email or password"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Logged out"
end
end
My routes are as follows:
get "log_in" => "sessions#new", :as => "log_in"
get "log_out" => "sessions#destroy", :as => "log_out"
get "sign_up" => "users#new", :as => "sign_up"
#get "my_account" => "users#show", :as => "my_account"
get "my_account" => "users#edit", :as => "my_account"
get "main/index"
resources :users
resources :sessions
Finally, my Application controller and aplication.html:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user
private
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
end
In application.html is where I used the current_user method:
<div id="user_nav">
<% if current_user %>
Logged in as <%= current_user.email %>
<%= link_to "Log out", log_out_path %>
<%= link_to "My Account", my_account_path %>
<% else %>
<%= link_to "Sign up", sign_up_path %>
<%= link_to "Log in", log_in_path %>
<% end %>
</div>

I am not sure why you are using
if #user.update(:current_user)
It should be something like:
if #user.update(user_params)

I know this is simple and maybe you already corrected this but...
instead of
if #user.update(user_paramas)
try
if #user.update(user_params)

Related

:id=> nil missing required keys :id

I am creating a new app with simple authentication, but i get this error:
No route matches {:action=>"show", :controller=>"users", :id=>nil},
missing
required keys: [:id]
I have tried other stackoverflow solutions but none have seemed to work for me.
This is my users_controller:
class UsersController < ApplicationController
def new; end
def create
#user = User.create(password: params[:password], email: params[:email],
firstname: params[:firstname], lastname: params[:lastname])
redirect_to user_path(#user)
end
def show
#user = User.find(params[:id])
end
end
My sessions controller:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: "Logged in!"
else
flash.now[:alert] = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = 1
redirect_to root_url, notice: "Logged out!"
end
end
routes.rb :
Rails.application.routes.draw do
# Fubyonrails.org/routing.html
root :to => 'static#welcome'
resources :users, only: [:new, :create, :show]
resources :sessions, only: [:new, :create, :destroy]
resources :studios
end
<h1> Hey, <%= #user.firstname %>! </h1>
<h3>Home</h3>
<%= link_to "Log Out", session_path, method: :delete %>
<%= stylesheet_link_tag 'users', media: 'all', 'data-turbolinks-track' =>
true %>
The problem is after create a user? If yes, make sure that the user is being created and exists. The problem could be that #user is nil
Check your user_show route it would be like
users/:id/show
You have to pass param id along with your request to show that id object. Right now you're call is missing param id.
You're call should be like this
users/1/show
Where as 1 is the user id in DB

Can't seem to login

I've been spending a few hours trying to understand sessions and I can't seem to get logged in. I hope someone can tell me what I'm doing wrong.
Application Controller
protect_from_forgery with: :exception
helper_method :current_user
def current_user
#current_user ||= User.find(session[:user_id]) if session[:user_id]
end
def authorize
redirect_to '/' unless current_user
end
Session Controller
class SessionsController < ApplicationController
def new
end
def create
#user = User.where(email: params[:email]).first
if #user && #user.authenticate(params[:session][:password])
session[:user_id] = user.id
redirect_to '/'
else
redirect_to '/sessions/new'
end
end
def destroy
session[:user_id] = nil
redirect_to '/'
end
end
User Controller
class UsersController < ApplicationController
before_action :find_user, only: [:show, :edit, :update, :destroy]
def index
#user = User.all
end
def new
#user = User.new
end
def create
#user = User.new(user_params)
if #user.save!
redirect_to '/'
else
render 'new'
end
end
def show
end
def edit
end
def update
if #user.update
redirect_to '/'
else
render 'edit'
end
end
def destroy
#user.destroy
redirect_to '/'
end
private
def find_user
#user = User.find(params[:id])
end
def user_params
params.require(:user).permit(:email, :username, :password, :about_me)
end
end
Sessions/new
<%= form_tag('/sessions', method: "POST") do %>
Email: <%= email_field_tag :email %>
Password: <%= password_field_tag :password %>
<%= submit_tag 'Submit' %>
<% end %>
Routes
root 'users#index'
resources :sessions, only: [:new, :create, :destroy]
resources :users
If there are additional code that would be required please let me know. Also if you know a better convention in order to add login for my user, I'm open to learn different ways. Thank you for everyone help in understanding this problem.

Rails undefined method for nil:NilClass

I get this error while clicking in form Log In button:
undefined method `[]' for nil:NilClass
View with signup form is below:
<%= form_for(:session, url: login_path) do |f| %>
<%= f.text_field :login, :placeholder => "login" %>
<%= f.password_field :password, :placeholder => "Password" %>
<%= f.submit "Log in", class: "btn-submit"%>
<% end %>
SessionsController :
class SessionsController < ApplicationController
def new
end
def create
#user = User.find_by_login(params[:login][:password]) ////ERROR LINE
if #user && #user.authenticate(params[:session][:password])
session[:user_id] = #user.id
redirect_to '/'
else
flash.now[:danger] = 'err'
redirect_to '/login'
end
end
def destroy
session[:user_id] = nil
redirect_to '/'
end
end
User controller:
class UsersController < ApplicationController
def new
#users = User.new
end
def create
#user = User.new(user_params)
if #user.save
session[:user_id] = #user.id
current_user = #user.id
redirect_to #user
else
redirect_to '/login'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :login)
end
end
Routes:
get 'logout' => 'sessions#destroy'
post 'logout' => 'sessions#destroy'
delete 'logout' => 'sessions#destroy'
get 'login' => 'sessions#new'
post 'login' => 'sessions#create'
resources :users, :user_types
Also, I do not want to create 'signup' view - there should be no possibility to create user through website
Looking at your form, I don't think you have params[:login]. So it'll be nil and params[:login][:password] is evaluated to nil[:password]. That's why you have the error.
What you have, according to the form, should be params[:session][:login] and params[:session][:password]. So the only remaining question is how you implemented your User.find_by_login method.

Send email notification to follower

I want to send an email notification to an user x when user y is starting to follow user x
I have the following method in my follows controller:
class FollowsController < ApplicationController
before_action :authenticate_user!
def create
#user = User.find(params[:id])
if #user.present?
current_user.follow!(#user)
ModelMailer.new_follower_notification(#user).deliver
end
end
def destroy
#user = User.find(params[:id])
if #user.present?
follow = current_user.follows.get_follow(#user).first if current_user.follows
if follow
follow.destroy
end
end
respond_to do |format|
format.js { render :file => "/follows/create", :handlers => [:erb] }
end
end
end
My modelmailer:
def new_follower_notification(user)
#user = user
mail to: user.email, subject: "#{#user.name}, you are now followd by others.", bcc: "oliviervanhees#gmail.com"
end
In my view folder I have a create.js.erb file
<% if #user %>
$('#user_<%= #user.id %>').html('<%= escape_javascript(render :partial => 'users/user', :locals => { :user => #user }) %>');
<% end %>
And this in my routes file:
match '/users/:id/follow' => 'follows#create', :as => :user_follow, :via => [:post]
match '/users/:id/unfollow' => 'follows#destroy', :as => :user_unfollow, :via => [:delete]
I try to trigger the model mailer, however I get errors by doing so. I think it is because I am using JSON here. Anyone any suggestions who to resolve this?

Rails Login as admin using bootstrap modal

I've spent several days on it, but couldn't carry out. I wonder how can I make logging in as admin using a Bootstrap Modal either when clicking on a link or visiting /admin page.
I made an admin namespace
namespace :admin do
resources :users
resources :shops
match '/index' => 'shops#index', :via => :get, :as => 'index'
get '', to: 'sessions#new', as: '/'
end
and also Users & Shop controllers and views in /admin folder.
Different solutions on the web couldn't work and that's why I decided to make it from the very beginning.
Just say if any other information about application is needed. Relying on your knowledge, I will be grateful for any help!
PS: Authentication method in application is taken from Hartl's tutorial (there's no authentication libraries).
Login page (/admin), views/admin/sessions/new.html.erb:
<% provide(:title, "Sign in") %>
<h1>Sign in as admin</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
And also, if non-admin tries to access /admin page, he will be redirected ro the 'login as admin' page. controllers/admin/users_controller.rb has admin_user for show action:
class Admin::UsersController < ApplicationController
before_action :signed_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: [:show, :destroy]
def index
#users = User.paginate(page: params[:page])
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
flash[:success] = "Welcome to the Hotels Advisor!"
redirect_to root_url
else
render 'new'
end
end
def edit
end
def update
if #user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to [:admin, #user]
else
render 'edit'
end
end
def destroy
user = User.find(params[:id])
unless current_user?(user)
user.destroy
flash[:success] = "User deleted."
end
redirect_to admin_users_url
end
private
def user_params
params.require(:user).permit(:name, :email, :password,
:password_confirmation)
end
# Before filters
def creating_forbidden
if signed_in?
redirect_to root_url, notice: "You are already regsitered."
end
end
def correct_user
#user = User.find(params[:id])
redirect_to(root_url) unless current_user?(#user)
end
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end

Resources