Finish user edit, update, index, and destroy actions

parent 97f2dba7
Pipeline #1288 failed with stages
in 0 seconds
...@@ -7,7 +7,7 @@ gem 'image_processing', '1.9.3' ...@@ -7,7 +7,7 @@ gem 'image_processing', '1.9.3'
gem 'mini_magick', '4.9.5' gem 'mini_magick', '4.9.5'
gem 'active_storage_validations', '0.8.9' gem 'active_storage_validations', '0.8.9'
gem 'bcrypt', '3.1.16' gem 'bcrypt', '3.1.16'
gem 'faker', '2.11.0' gem 'faker', '2.18'
gem 'will_paginate', '3.3.0' gem 'will_paginate', '3.3.0'
gem 'bootstrap-will_paginate', '1.0.0' gem 'bootstrap-will_paginate', '1.0.0'
gem 'puma', '5.3.1' gem 'puma', '5.3.1'
......
...@@ -109,7 +109,7 @@ GEM ...@@ -109,7 +109,7 @@ GEM
crass (1.0.6) crass (1.0.6)
erubi (1.10.0) erubi (1.10.0)
execjs (2.8.1) execjs (2.8.1)
faker (2.11.0) faker (2.18.0)
i18n (>= 1.6, < 2) i18n (>= 1.6, < 2)
ffi (1.15.1) ffi (1.15.1)
formatador (0.2.5) formatador (0.2.5)
...@@ -284,7 +284,7 @@ DEPENDENCIES ...@@ -284,7 +284,7 @@ DEPENDENCIES
bootstrap-will_paginate (= 1.0.0) bootstrap-will_paginate (= 1.0.0)
byebug (= 11.1.3) byebug (= 11.1.3)
capybara (= 3.35.3) capybara (= 3.35.3)
faker (= 2.11.0) faker (= 2.18)
guard (= 2.16.2) guard (= 2.16.2)
guard-minitest (= 2.4.6) guard-minitest (= 2.4.6)
image_processing (= 1.9.3) image_processing (= 1.9.3)
......
@import "bootstrap"; @import "bootstrap";
.center { .center {
text-align: center; text-align: center;
h1 { h1 {
...@@ -51,17 +52,21 @@ p { ...@@ -51,17 +52,21 @@ p {
list-style: none; list-style: none;
} }
li a { li a {
color: #fff; color: rgb(96, 125, 255);
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
padding: 4px 10px; padding: 4px 10px;
text-decoration: none; text-decoration: none;
&:hover { &:hover {
color: #000; color: rgb(5, 0, 73);
text-decoration: none; text-decoration: none;
} }
} }
#navbarSupportedContent {
color: #fff;
}
.jumbotron { .jumbotron {
border-bottom: 10%; border-bottom: 10%;
background-color: #dadada; background-color: #dadada;
...@@ -158,3 +163,15 @@ input { ...@@ -158,3 +163,15 @@ input {
width: auto; width: auto;
margin-left: 0; margin-left: 0;
} }
.users {
list-style: none;
margin: 0;
li {
overflow: auto;
padding: 10px 0;
border-bottom: 1px solid rgb(224, 224, 224);
}
}
...@@ -9,8 +9,7 @@ class SessionsController < ApplicationController ...@@ -9,8 +9,7 @@ class SessionsController < ApplicationController
if user && user.authenticate(params[:session][:password]) if user && user.authenticate(params[:session][:password])
log_in user log_in user
params[:session][:remember_me] == '1' ? remember(user) : forget(user) params[:session][:remember_me] == '1' ? remember(user) : forget(user)
remember user redirect_back_or user
redirect_to user
else else
flash.now[:danger] = 'Invalid email/password combination' flash.now[:danger] = 'Invalid email/password combination'
render 'new' render 'new'
......
class UsersController < ApplicationController class UsersController < ApplicationController
include SessionsHelper
before_action :logged_in_user, only: [:index, :edit, :update, :destroy]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user,
only: :destroy
def show def show
@user = User.find(params[:id]) @user = User.find(params[:id])
end end
def index
@users = User.paginate(page: params[:page])
end
def new def new
@user = User.new @user = User.new
end end
...@@ -19,8 +29,47 @@ class UsersController < ApplicationController ...@@ -19,8 +29,47 @@ class UsersController < ApplicationController
end end
end end
def edit
@user = User.find(params[:id])
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
private private
def user_params def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation) params.require(:user).permit(:name, :email, :password, :password_confirmation)
end end
def logged_in_user
unless logged_in?
store_location
flash[:danger] = "Please log in."
redirect_to login_url
end
end
def correct_user
@user = User.find(params[:id])
redirect_to(root_url) unless current_user?(@user)
end
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted"
redirect_to users_url
end
# Confirms an admin user.
def admin_user
redirect_to(root_url) unless current_user.admin?
end
end end
...@@ -23,6 +23,11 @@ module SessionsHelper ...@@ -23,6 +23,11 @@ module SessionsHelper
end end
end end
# Returns true if the given user is the current user.
def current_user?(user)
user && user == current_user
end
def logged_in? def logged_in?
!current_user.nil? !current_user.nil?
end end
...@@ -46,4 +51,15 @@ module SessionsHelper ...@@ -46,4 +51,15 @@ module SessionsHelper
session.delete(:user_id) session.delete(:user_id)
@current_user = nil @current_user = nil
end end
#Redirects to stored location (or to the default).
def redirect_back_or(default)
redirect_to(session[:forwarding_url] || default)
session.delete(:forwarding_url)
end
# Stores the URL trying to be accessed.
def store_location
session[:forwarding_url] = request.original_url if request.get?
end
end end
...@@ -7,7 +7,7 @@ class User < ApplicationRecord ...@@ -7,7 +7,7 @@ class User < ApplicationRecord
format: { with: VALID_EMAIL_REGEX }, format: { with: VALID_EMAIL_REGEX },
uniqueness: true uniqueness: true
has_secure_password has_secure_password
validates :password, presence: true, length: { minimum: 6 } validates :password, presence: true, length: { minimum: 6 }, allow_nil: true
# Returns the hash digest of the given string. # Returns the hash digest of the given string.
def User.digest(string) def User.digest(string)
......
...@@ -9,14 +9,14 @@ ...@@ -9,14 +9,14 @@
<li><%= link_to "Home",root_path %></li> <li><%= link_to "Home",root_path %></li>
<li><%= link_to "Help", help_path %></li> <li><%= link_to "Help", help_path %></li>
<% if logged_in? %> <% if logged_in? %>
<li><%= link_to "Users", '#' %></li> <li><%= link_to "Users", users_path %></li>
<li class="dropdown"> <li class="dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Account Account
</a> </a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDropdown"> <ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="navbarDropdown">
<li><%= link_to "Profile", current_user %></li> <li><%= link_to "Profile", current_user %></li>
<li><%= link_to "Settings", '#' %></li> <li><%= link_to "Settings", edit_user_path(current_user) %></li>
<li><hr class="dropdown-divider"></li> <li><hr class="dropdown-divider"></li>
<li> <li>
<%= link_to "Log out", logout_path, method: :delete %> <%= link_to "Log out", logout_path, method: :delete %>
......
<li>
<%= gravatar_for user, size: 50 %>
<%= link_to user.name, user %>
<% if current_user.admin? && !current_user?(user) %>
| <%= link_to "delete", user, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</li>
\ No newline at end of file
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 offset-md-3">
<%= form_with(model: @user, local: true) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Save changes", class: "btn btn-primary" %>
<% end %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="https://gravatar.com/emails" target="_blank">change</a>
</div>
</div>
</div>
\ No newline at end of file
<% provide(:title, 'All users') %>
<h1>All users</h1>
<%= will_paginate %>
<ul class="users">
<%= render @users %>
</ul>
<%= will_paginate %>
\ No newline at end of file
Rails.application.routes.draw do Rails.application.routes.draw do
get 'sessions/new'
root 'static_pages#home' root 'static_pages#home'
get '/home', to: 'static_pages#home' get '/home', to: 'static_pages#home'
get '/help', to: 'static_pages#help' get '/help', to: 'static_pages#help'
......
class AddAdminToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :admin, :boolean, default: false
end
end
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_06_17_022511) do ActiveRecord::Schema.define(version: 2021_06_22_035322) do
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "name" t.string "name"
...@@ -19,6 +19,7 @@ ActiveRecord::Schema.define(version: 2021_06_17_022511) do ...@@ -19,6 +19,7 @@ ActiveRecord::Schema.define(version: 2021_06_17_022511) do
t.datetime "updated_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false
t.string "password_digest" t.string "password_digest"
t.string "remember_digest" t.string "remember_digest"
t.boolean "admin", default: false
t.index ["email"], name: "index_users_on_email", unique: true t.index ["email"], name: "index_users_on_email", unique: true
end end
......
# This file should contain all the record creation needed to seed the database with its default values. # Create a main sample user.
# The data can then be loaded with the bin/rails db:seed command (or created alongside the database with db:setup). User.create!(name: "Example User",
# email: "example@railstutorial.org",
# Examples: password: "foobar",
# password_confirmation: "foobar",
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) admin: true)
# Character.create(name: 'Luke', movie: movies.first) # Generate a bunch of additional users.
99.times do |n|
name = Faker::Name.name
email = "example-#{n+1}@railstutorial.org"
password = "password"
User.create!(name: name,
email: email,
password: password,
password_confirmation: password)
end
\ No newline at end of file
...@@ -3,3 +3,8 @@ michael: ...@@ -3,3 +3,8 @@ michael:
name: Michael Example name: Michael Example
email: michael@example.com email: michael@example.com
password_digest: <%= User.digest('password') %> password_digest: <%= User.digest('password') %>
archer:
name: Sterling Archer
email: duchess@example.gov
password_digest: <%= User.digest('password') %>
\ No newline at end of file
require "test_helper"
class UsersEditTest < ActionDispatch::IntegrationTest
def setup
@user = users(:michael)
end
test "unsuccessful edit" do
get edit_user_path(@user)
assert_template 'users/edit'
patch user_path(@user), params: { user: { name: "",
email: "foo@invalid",
password: "foo",
password_confirmation: "bar" } }
assert_template 'users/edit'
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment