【问题标题】:Ruby on Rails - Store current Url to redirect after destroyRuby on Rails - 存储当前 URL 以在销毁后重定向
【发布时间】:2016-01-08 09:02:48
【问题描述】:

由于我在操作前进行了登录检查,因此在删除对象时我无法使用redirect_back

哪一个是将当前url 存储在某处的最佳方式,可能在session helper,然后在任何控制器中重定向到该值?

请帮忙,这个问题正在影响我所有关联的控制器。

重定向返回让我编辑/显示,现在为零。

我目前正在从父级删除:

module SessionsHelper

  # Logs in the given user.
  def log_in(user)
    session[:user_id] = user.id
  end

  # Remembers a user in a persistent session.
  def remember(user)
    user.remember
    cookies.permanent.signed[:user_id] = user.id
    cookies.permanent[:remember_token] = user.remember_token
  end

  # Returns the current logged-in user (if any).
  def current_user
    @current_user ||= User.find_by(id: session[:user_id])
  end

  # Returns true if the user is logged in, false otherwise.
  def logged_in?
    !current_user.nil?
  end

 # Forgets a persistent session.
  def forget(user)
    user.forget
    cookies.delete(:user_id)
    cookies.delete(:remember_token)
  end

  # Logs out the current user.
  def log_out
    forget(current_user)
    session.delete(:user_id)
    @logs = Log.create(user_id: current_user.id, role_id: current_user.role_id, action:"Logoff")
    @current_user = nil
  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

def store_location
     session[:forwarding_url] = request.url if request.get?
end 

end





class AddressesController < ApplicationController
    before_action :logged_in_user

    def address_params
        params.require(:address).permit(:id, :no, :street, :suburb, :code, :details, :city_id, :addressable_type, :addressable_id)
    end


    def new
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canwrite?)
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"New")
            @addresses = Address.new(:addressable_type => params[:addressable_type],:addressable_id => params[:addressable_id])
        else
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"New !Access Denied! ")
        flash[:notice] = "You don't have access to create Addresses."
        redirect_to :back
        end
    end

    def create
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canwrite?)
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Create", details: address_params)
            @address = Address.new(address_params)
            if @address.save
            flash[:notice] = 'Address Saved'
            redirect_to @address.addressable
            else
            render "new"
            end
        else
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Create !Access Denied! ")
        flash[:notice] = "You don't have access to create Addresses."
        redirect_to :back
        end
    end


    def edit
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canupdate?)
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Edit", details: params[:id])
            @addresss = Address.find(params[:id])
        else
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Edit !Access Denied! ", details: params[:id])
        flash[:notice] = "You don't have access to edit Addresses."
        redirect_to :back
        end
    end

    def update
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canupdate?)
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Update", details: address_params)
            @addresss = Address.find(params[:id])
            if @addresss.update_attributes(address_params)
            redirect_to @address.addressable
                flash[:notice] = 'Account Updated'
            else 
            render "edit"
            flash[:error]
            end
        else
        flash[:notice] = "You don't have access to edit Addresss."
        redirect_to back
        end
    end

    def show
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canread?)
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"View", details: params[:id])
            @addresses = Address.find(params[:id])
        else
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"View !Access Denied! ", details: params[:id])
        flash[:notice] = "You don't have access to view Addresss."
        redirect_to back
        end
    end

    def destroy
        if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:candelete?)
            @address = Address.find(params[:id])
            @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Delete", details: params[:id])
            @address.destroy
            redirect_to :back
            flash[:notice] = 'Address Deleted'
        else
        flash[:notice] = "You don't have access to delete Addresss."
        redirect_to :back
        end
    end


    # Before Filters

    # Confirms if User is logged-in
    def logged_in_user
     unless logged_in?
     flash[:danger] = "Please log in."
     redirect_to root_path
     end
    end
end

【问题讨论】:

  • 我认为您不能执行redirect_to :back,因为之前的视图是已删除对象的show 页面?我不明白为什么您的logged_in 支票与此有关。你是说如果你删除那个检查你可以重定向?你能展示一些示例代码吗?
  • logged_in 检查存储当前 url,与访问权限相同,因此重定向返回将我发送到显示/编辑路径,在这种情况下我需要重定向 2 步。 redirect_back 或 redirect_to back 都具有相同的效果,并且它们在身份验证方面工作良好。所以我真的需要一个辅助路径存储位置或学习如何设置重定向到 2 步后退

标签: ruby-on-rails ruby destroy


【解决方案1】:

您可以存储多个 redirect_to 路径...最好在 ApplicationController 中使用单独的 before_action 来执行此操作

before_action :store_back_paths

def store_back_paths

  # if session[:back_path] doesn't exist, create it as an empty array

  session[:back_path] ||= []

  # add the current path as a new entry in the array

  session[:back_path] << request.referer

  # while there are more than five entries, drop the oldest entries 
  # this is to ensure we're not storing too many entries

  session[:back_path].shift while session[:back_path].count > 5
end

在进行正常重定向时,使用 pop 删除数组中的最后一个元素并返回删除的值。

redirect_to session[:back_path].pop

在销毁后进行重定向时,删除最后一个条目(指向被销毁项目的显示页面),然后重定向到之前的路径。

session[:back_path].pop # drops the last entry   
redirect_to session[:back_path].pop

【讨论】:

  • 那很好,我在想这样的事情,按顺序存储最后 3 个,但我缺乏知识限制了我。我已经添加了代码,所以如果您有时间更好地解释,我将永远感激不尽
  • 好的,我已经将它改造成更有用的代码并添加了更多解释。
【解决方案2】:

我只是在我提交删除之前存储我想去的位置:

def destroy
  @child = Child.find_by params[:id]
  parent = @child.parent # or whatever
  @child.destroy
  flash[:notice] = 'Deleted'
  redirect_to parent
end

如果你想存储在一个会话中,我不使用它来销毁,而是做其他事情:

def destroy
  @child = Child.find_by params[:id]
  session[:return_link] = parent_path(@child.parent) # or whatever
  @child.destroy
  flash[:notice] = 'Deleted'
  redirect_to session[:return_link]
end

当然,您可以设置并从任何点返回,我使用它来允许用户导航站点的子部分,然后退出,通过在执行显示操作时记录活动引用者到子部分,以及会话路径的显示按钮确实会在他们随时加入的退出点退出。

你必须添加一些测试来设置它,如果你没有设置它,你当然应该使用链接。

【讨论】:

  • 谢谢,我会尝试第二个选项。我正在使用多态表,不确定是否可以使用第一个选项,我可以通过多态更改/使用 .parent 吗?
  • 对不起。 .parent 是一个示例类。请插入您自己的方法 - 通常对于多态,我在您定义的基类中放置了一个 belongs_to,然后所有子类都有所属。然后使用belongs_to是什么。这假设所有多态类belongs_to某种类型的对象,如果不是,则为每种类型的类定义一个get_parent方法,该方法确实返回父(或您想要的对象)的路径得到..)
猜你喜欢
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2012-09-26
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2014-02-21
  • 1970-01-01
相关资源
最近更新 更多