主頁 > 軟體工程 > 銷毀操作中的重定向無法正常作業

銷毀操作中的重定向無法正常作業

2022-04-21 21:26:10 軟體工程

我正在使用 Ruby on Rails 構建一個簡單的博客應用程式,它允許用戶根據權限和限制登錄/注銷、注冊并對其文章和個人資料執行操作。我遇到了銷毀用戶操作的問題。在 users/index 視圖中(列出所有現有用戶),由于 url 路徑不包含 {:id},它不會導致錯誤,但 redirect_to root_path 不起作用。如果在用戶/顯示頁面(包含一些資訊和相關文章的個人資料頁面)中執行相同的操作,由于 url 是 localhost/users/id,當用戶被洗掉時,我得到“找不到用戶” id'=33” 錯誤如下所示。如果我手動轉到根路由,則會顯示成功的帳戶洗掉訊息并且操作正確執行。所以這不是 DESTROY 不起作用,而是重定向我相信。我已經嘗試重定向到不同的路徑,但它仍然不起作用。以下是相關檔案:

路線.rb

Rails.application.routes.draw do
root "pages#home"
get "about", to: "pages#about"

resources :articles

get "signup", to: "users#new"
resources :users, except: [:new] 

get 'login', to: 'sessions#new'
post 'login', to: 'sessions#create'
get 'logout' => :destroy, to: 'sessions#destroy'
end

pages_controller

class PagesController < ApplicationController
def home
    redirect_to articles_path if logged_in?
end

def about
end         
end

users_controller

class UsersController < ApplicationController
before_action :set_user, only: [:show, :edit, :update, :destroy]
before_action :require_user, only: [:edit, :update]
before_action :require_same_user, only: [:edit, :update, :destroy]

def index
    @users = User.all
end

def show
    @articles = @user.articles
end

def new
    @user = User.new
end

def edit
end

def create
    @user = User.new(user_params)
    if(@user.save)
        session[:user_id] = @user.id  #logs user in automatically once they are signed up
        flash[:notice] = "Welcome to AlphaBlog, #{@user.username}!"
        redirect_to articles_path
    else
        render 'new'
    end
end

def update
    if @user.update(user_params)
        flash[:notice] = "Account updated!"
        redirect_to @user
    else
        render 'edit'
    end
end

def destroy
    @user.destroy
    session[:user_id] = nil
    flash[:notice] = "Account and all associated articles deleted!"
    redirect_to root_path
end

private
def user_params
    params.require(:user).permit(:username, :email, :password)
end

def set_user
    @user = User.find(params[:id])
end

def require_same_user
    if current_user != @user
        flash[:alert] = "You can only edit your own profile!"
        redirect_to current_user
    end
end

end

session_controller

class SessionsController < ApplicationController

def new
end

def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
        session[:user_id] = user.id
        flash[:notice] = "Logged in successfully!"
        redirect_to user
    else
        flash.now[:alert] = "There was something wrong with your login details!"
        render 'new'
    end

end

def destroy
    session[:user_id] = nil
    flash[:notice] = "Logged out."
    redirect_to root_path
end

end

用戶/index.html.erb

<div class = "header">
<h1>
    AlphaBlog
    <% if logged_in? %>
        <%= link_to 'Articles', articles_path, method: :get, class: "index-button-to" %>
    <% else %>
        <%= link_to 'Home', root_path(), method: :get, class: "index-button-to" %>
        <%= link_to 'Articles', articles_path, method: :get, class: "index-button-to" %>
    <% end %>
    <%= render 'layouts/log_in_out_navigation'%>
</h1>
</div>

<h2>Alpha Bloggers</h2>

<div >
<%# cycle through all articles and show them all in a table %>
<% @users.each do |user| %>

    <div class = "index-article-container">

        <div  style = "color:rgb(16, 136, 255);">
            <%= user.username %>
        </div>

        <div class="white">

            <div class="index-article-title">
                <%= gravatar_for(user, size: 150) %>
            </div>

            <div >
                <%# gives the plural word for multiple articles %>
                <%= pluralize(user.articles.count, "article") %>
            </div>

            <div class="index-article-actions">
                <%# shows selected article page %>
                <%= link_to 'View Profile', user, class: "index-link-to show" %>
                <% if logged_in? && current_user.username == user.username %>
                    <%# shows selected article EDIT page. edit_article_path because in routes, 
the prefix for edit is edit_article && (article) because we need the id for the path as well%>
                    <%= link_to 'Edit Profile', edit_user_path(user), data: { turbo_method: 
:get}, class: "index-link-to edit" %>
                    <%= link_to 'Delete Profile', user_path(current_user), data: { 
turbo_method: :delete, turbo_confirm: "Are you sure? (This will also delete all of your 
articles)" }, class: "index-link-to delete" %>
                <% end %>
            </div>
                    
        </div>
                    

        <div class="index-created-updated">
            Joined <%= time_ago_in_words(user.created_at) %> ago.
        </div>

    </div>
    
<% end %>

用戶/show.html.erb

<div class = "header">
<h1>
    AlphaBlog
    <% if logged_in? %>
        <%= link_to 'Articles', articles_path, method: :get, class: "index-button-to" %>
        <%= link_to 'Bloggers', users_path, method: :get, class: "index-button-to" %>
    <% else %>
        <%= link_to 'Home', root_path(), method: :get, class: "index-button-to" %>
        <%= link_to 'Articles', articles_path, method: :get, class: "index-button-to" %>
        <%= link_to 'Bloggers', users_path, method: :get, class: "index-button-to" %>
    <% end %>
    <%= render 'layouts/log_in_out_navigation'%>
</h1>
</div>

<h2> <%= @user.username %>'s profile </h2>

<div >
<%# gravatar_for method created in helpers/application_helper %>
<%= gravatar_for @user, size: 200 %>
<% if logged_in? && current_user.username == @user.username %>
    <div >
        <%= link_to "Edit Profile", edit_user_path(@user), class: "index-link-to edit" %>
        <%= link_to 'Delete Profile', user_path(current_user), data: { turbo_method: :delete, 
turbo_confirm: "Are you sure? (This will also delete all of your articles)" }, class: "index- 
link- 
to delete", style: "margin-top:0.3vh" %>
    </div>
<% end %>
</div>

<h3 style = "text-align:center">Articles</h3>
<%= render 'articles/article' %>

錯誤頁面 銷毀操作中的重定向無法正常作業

uj5u.com熱心網友回復:

我認為這里的答案實際上是您的路線和控制器的布局非常不同(或者首先不重新啟動輪子)。如果您創建一個管理其他用戶的系統,則通過引數傳遞用戶 ID 會很好 - 但當用戶管理他們自己的組態檔時,它會非常不穩定。

例如,這是用戶在 vanilla Devise 設定中 CRUD 自己的組態檔的方式:

Verb    URI Pattern               Controller#Action                    
------------------------------------------------------------------------
GET     /users/cancel(.:format)   devise/registrations#cancel 
GET     /users/sign_up(.:format)  devise/registrations#new
GET     /users/edit(.:format)     devise/registrations#edit
PATCH   /users(.:format)          devise/registrations#update                                                                          
PUT     /users(.:format)          devise/registrations#update                                                                          
DELETE  /users(.:format)          devise/registrations#destroy                                                                         
POST    /users(.:format)          devise/registrations#create  

請注意 URI 模式中缺少:id引數。那是因為它暗示有問題的資源是當前登錄的用戶,并且用戶是通過會話(或令牌)識別的。

Registrations如果程式員以后想添加一個 UsersController 來管理其他用戶,控制器的命名是為了避免歧義

如果您想做類似的事情,您可以 使用resource宏而不是resources.

# routes for user registration
resource :registrations, 
    only: [:new, :edit, :update, :create, :destroy]

# routes for viewing other users 
resources :users, only: [:index, :show]

這將產生:

Prefix                Verb   URI Pattern                    Controller#Action
-----------------------------------------------------------------------
new_registrations     GET    /registrations/new(.:format)   registrations#new
edit_registrations    GET    /registrations/edit(.:format)  registrations#edit
registrations         GET    /registrations(.:format)       registrations#show    
                      PATCH  /registrations(.:format)       registrations#update  
                      PUT    /registrations(.:format)       registrations#update  
                      DELETE /registrations(.:format)       registrations#destroy
                      POST   /registrations(.:format)       registrations#create

隨意命名。這里的核心要點是不要混淆兩個完全不同的問題——用戶管理用戶注冊,并且每個職責都有單獨的端點和控制器。

然后在您的控制器中,您只需從會話中對用戶進行身份驗證,如果用戶未通過身份驗證,則重定向用戶:

# Handles user account registration, updates and deleting accounts
class RegistrationsController < ApplicationController
  before_action :require_user, except: [:new, :create]

  # Displays the form for signing up a user
  # GET /registrations
  def new
    @user = User.new
  end

  # Register a new user and sign them in
  # POST /registrations
  def create
    @user = User.new(user_params)
    if @user.save 
      reset_session # avoids session fixation attacks
      session[:user_id] = @user.id  #logs user in automatically once they are signed up
      flash[:notice] = "Welcome to AlphaBlog, #{@user.username}!"
      redirect_to articles_path
    else
      render :new
    end
  end

  # Form for editing the users own profile
  # GET /registrations/edit
  def edit
    @user = current_user
  end

  # Update the currently signed in user
  # PATCH /registrations
  def update
    @user = current_user
    if @user.update(user_params)
      flash[:notice] = "Account updated!"
      redirect_to current_user
    else
      render :new
    end
  end

  # Cancel the current users registration 
  # DELETE /registrations
  def delete
    current_user.delete
    reset_session # avoids session fixation attacks
    flash[:notice] = "Account and all associated articles deleted!"
    redirect_to root_path
  end
  
  private 

  def user_params
    params.require(:user).permit(:username, :email, :password)
  end
end
# Displays users
# Managing accounts is handled by RegistrationsController
class UsersController < ApplicationController
  # GET /users
  def index
    @users = User.all
  end
  
  # GET /users/1
  def show
    @user = User.find(params[:id])
    @articles = @user.articles
  end
end

由于它們在路徑中沒有 id,因此您需要將洗掉按鈕設定為發送到正確的路徑:

<%= button_to "Delete your account", registrations_path, method: :delete %>

并調整您的表格:

<%= form_with(model: @user, url: registrations_path) do |form| %>
  # ...
<% end %>

這樣做的正確方法實際上是像 Devise 那樣做,并且有一個正常的鏈接,將 GET 請求發送到“你確定要洗掉你的帳戶嗎?” 然后頁面要求用戶輸入他們的密碼或電子郵件并提交洗掉請求,以便用戶不會意外洗掉他們的帳戶。

但話又說回來,除非你想要一個漫長而乏味的輪子制造課程,否則不要重新發明認證輪子。

uj5u.com熱心網友回復:

所以我最終使用max's answer的簡化版本自己解決了這個問題。

發生錯誤是因為銷毀操作在此行中為會話的用戶 IDusers_controller分配了一個值nil

session[:user_id] = nil

這導致應用程式拋出那個丑陋的錯誤,盡管操作本身正在正確執行,因為user_id在 的其他操作中需要a users_controller(在錯誤的情況下,set_user.

我通過在as中取出users_controller取出 destroy 動作解決了這個問題,這樣它就可以獨立于其他代碼,并為這個動作創建了一個特定的路線。sessions_controllerdestroy_userusers_controller

所以總結一下:

  1. 洗掉銷毀users_controller

  2. 添加destroy_user如下sessions_controller

    def destroy_user
        @user = User.find_by(id: session[:user_id])
        if current_user != @user
            flash[:alert] = "You can only edit your own profile!"
            redirect_to current_user
        end
        @user.destroy
        session[:user_id] = nil
        flash[:notice] = "Account and all associated articles deleted!"
        redirect_to root_path
    end
    
  3. 將此路徑添加到routes.rb

    get 'destroy_user' => :destroy, to: 'sessions#destroy_user'
    
  4. 將洗掉組態檔鏈接更改為:

    <%= link_to 'Delete Profile', destroy_user_path(current_user), data: { 
    turbo_method: :delete, turbo_confirm: "Are you sure? (This will also delete all 
    of your articles)" }, class: "index-link-to delete" %>
    

uj5u.com熱心網友回復:

我不確定您是否真正了解了這一點。在您最初的方法中,我懷疑發生了兩件事:

  1. 在 users/index.html.erb 你有link_to 'Delete Profile', user_path(current_user),但我認為你想要user_path(user). 您目前擁有的每個洗掉按鈕都會嘗試洗掉同一個用戶。

  2. 錯誤表明您正在嘗試執行“顯示”而不是“破壞”這一事實使我懷疑您沒有正確加載渦輪增壓器。你沒有說你使用的是什么版本的 rails,但是對于早于 7 的版本,你沒有開箱即用的 turbo,你應該改用 UJS。將此https://guides.rubyonrails.org/getting_started.html#deleting-an-article與此https://guides.rubyonrails.org/v6.1/getting_started.html#deleting-an-article進行比較

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/460266.html

標籤:轨道上的红宝石 红宝石 重定向 粗鲁 破坏

上一篇:在Rails控制器中檢索當前引數值-錯誤:找不到沒有ID的問題

下一篇:為什么即使模型存在Rails也會回滾?

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more