【问题标题】:How do I maintain the same controller & action in a page URL upon re-rendering an action in Rails?在 Rails 中重新呈现操作时,如何在页面 URL 中维护相同的控制器和操作?
【发布时间】:2010-12-04 21:42:55
【问题描述】:

我正在使用 AuthLogic 对我的 rails 应用程序中的用户进行身份验证。该部分已正确设置并正常工作。

我定义了以下路线:

map.login '/account/login', :controller => :user_sessions, :action => :new

调用 rake 路由返回我期望的结果:

login /account/login {:controller=>"user_sessions", :action=>"new"}

当有人提交登录时,它会调用 UserSessionsController.create:

def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
        flash[:notice] = "Login successful!"
        redirect_back_or_default account_url
    else
        render :action => :new
    end
end

如果@user_session.save 失败,屏幕上会出现相应的错误消息。但是,浏览器 URL 也会更改为“http://localhost:3000/user_session”,而不是停留在“http://localhost:3000/account/login”。

我认为问题在于我提供给渲染方法的内容。我应该喂它什么?

【问题讨论】:

    标签: ruby-on-rails controller routes authlogic


    【解决方案1】:

    这实际上是此过程的预期行为。在标准的脚手架 RESTful 控制器中,createupdate 操作中的验证错误将简单地呈现原始模板而无需重定向。这将产生您所看到的内容 - new 模板将在 URL 栏中与 create 操作的 URL 一起显示。这样做的原因是,为了向用户显示发生了什么错误的信息,视图必须有权访问无效的模型对象,在您的情况下为 @user_session

    如果您想强制重定向到原始 URL,您可以使用 redirect_to 而不是 render,但这会导致您丢失有关错误的信息。您需要手动将错误保留在会话中,这会很混乱。我的建议是不要担心 URL 与原始 URL 不匹配这一事实,因为这在所有 Rails 应用程序中都是非常标准的。

    【讨论】:

    • 我很欣赏这个建议,但我发现强制的不一致令人不安。任何在页面上遇到错误并想要报告它的人最终都会链接到一个页面,该页面的链接在单击时没有意义。正如您所说,使用 redirect_to 并坚持错误也很麻烦。
    • 没有其他选择。数据必须以某种方式持久化。要么不进行重定向,要么将其存储在某个地方并重定向。
    • 我找到了一种简单的方法来实现我的目标,而不必以这种方式使我的控制器和视图复杂化。查看已接受的答案。
    【解决方案2】:

    只需为 Rails 4 添加解决方案(基于 Shaun 在此处的回答):

    向路由文件添加新路由:

    post '/carts/new' => 'carts#create', as: :create_post

    添加 url: create_post_path 到表单标签

    完成。

    【讨论】:

      【解决方案3】:

      经过进一步挖掘,我在另一个 StackOverflow 问题中找到了解决方案:Use custom route upon model validation failure

      我只是修改了我的路线以添加一个新的路线来摆姿势到“/account/login”:

      map.login '/account/login', :controller => :user_sessions, :action => :new, :conditions => {:method => :get}
      map.login_post '/account/login', :controller => :user_sessions, :action => :create, :conditions => {:method => :post}
      

      然后,我更新了我的视图以利用新路线:

      <% form_for @user_session, :url => login_post_path do |f| %>

      这非常有效。登录失败会给出相应的错误消息并维护“/account/login” URL。

      【讨论】:

        猜你喜欢
        • 2023-03-22
        • 2015-06-23
        • 1970-01-01
        • 1970-01-01
        • 2018-08-11
        • 1970-01-01
        • 1970-01-01
        • 2020-05-16
        • 2014-05-23
        相关资源
        最近更新 更多