【问题标题】:How do I display error messages in the same URL as the form URL in Rails forms?如何在与 Rails 表单中的表单 URL 相同的 URL 中显示错误消息?
【发布时间】:2013-04-08 15:49:49
【问题描述】:

(我已将最初属于这篇文章的第二个问题分解为a separate post

我正在使用 Rails 创建一个产品登录页面,用户可以在其中输入他们的电子邮件地址,以便在产品发布时收到通知。 (是的,有服务/宝石等可以为我做这件事,但我是编程新手,想自己构建它来学习 Rails。)

在提交表单时,如果出现错误,应用程序当前会重定向到“/invites” 我想在与原始表单相同的页面/URL 上显示错误消息? (在我的例子中,表单位于根目录,而错误消息显示在“/invites”)

我已经阅读了Rails Guide on Routes 和许多关于处理表单错误的 stackoverflow 帖子,我发现没有任何东西似乎可以回答我的问题。

更新:根据@rovermicrover 的回复,我想澄清一下,虽然我对 Ajax 解决方案持开放态度,但我可以刷新显示错误消息的页面。 (我无法获得 @rovermicrover 的建议以按预期运行 - 请参阅下面我对该解决方案的回复以了解更多详细信息。)

我做了什么:

邀请模特:

    class Invite < ActiveRecord::Base
      attr_accessible :email

      validates :email, :presence => {:message => "Please enter an email address."}

    end

我的路线文件:

SuggestionBoxApp::Application.routes.draw do
  root to: 'invites#new'
  resources :invites
end

这就是我在 Invites 控制器中的内容(我只包含了我所引用的操作:新建、创建、显示 - 它基本上是 Rails 可能生成的默认操作):

class InvitesController < ApplicationController

      def show
      @invite = Invite.find(params[:id])

        respond_to do |format|
          format.html # show.html.erb
          format.json { render json: @invite }
        end
      end

      def new
        @invite = Invite.new

        respond_to do |format|
          format.html # new.html.erb
          format.json { render json: @invite }
        end
      end

      def create
        @invite = Invite.new(params[:invite])

        respond_to do |format|
          if @invite.save
            format.html { redirect_to @invite }
            format.json { render json: @invite, status: :created, location: @invite }
          else
            format.html { render action: "new" }
            format.json { render json: @invite.errors, status: :unprocessable_entity }
          end
        end
      end
    end

如果我可以提供任何其他信息来帮助回答这个问题,请告诉我。谢谢!

【问题讨论】:

    标签: ruby-on-rails forms url


    【解决方案1】:

    将表单设为“远程”

    form_for @invite, :remote => true
       ....
    

    然后在控制器中

    def create
      @invite = Invite.new(params[:invite])
        respond_to do |format|
          if @invite.save
            format.html { redirect_to @invite }
            format.js { render :action => 'create_suc'}
          else
            format.html { render action: "new" }
            format.js { render :action => 'create_fail' }
          end
        end
      end
    

    /invites/create_suc.js.erb

    $('#errors').remove()
    $('#new_invite').prepend("<div class='Thanks'>Thanks for signing up</div>")
    $('#new_invite').hide("")
    

    /invites/create_fail.js.erb

    $('#new_invite').html('<%= escape_javascript render("form", :invite => @invite) %>');
    

    Forms 是您的.... 表单的一部分,也是对@invite 上所有错误的处理。

    【讨论】:

    • 感谢您的建议。我试过了,结果如下:在 create_fail 上,表单显示在同一页面上,但现在表单输入不显示。创建成功后,再次显示相同的页面(不是“/thanks”),并简要显示确认消息。无论如何,我不知道“远程”,所以将继续探索这个方向。谢谢!
    【解决方案2】:

    从纯粹的 Ruby on Rails 角度来看,有一种方法可以做到这一点,而无需使表单“远程”提交。但是,您只能在浏览器启用 cookie 的情况下执行此操作。

    想法是将表单数据保存在会话信息中以防出错。 只要记住在成功的情况下删除会话数据。

      def new
        @invite = Invite.new(session[:invite])
    
        respond_to do |format|
          format.html # new.html.erb
          format.json { render json: @invite }
        end
      end
    
      def create
        @invite = Invite.new(params[:invite])
    
        respond_to do |format|
          if @invite.save
            session.delete(:invite)
            format.html { redirect_to @invite }
            format.json { render json: @invite, status: :created, location: @invite }
          else
            session[:invite] = params[:invite]
            format.html { render action: "new" }
            format.json { render json: @invite.errors, status: :unprocessable_entity }
          end
        end
      end
    

    【讨论】:

      猜你喜欢
      • 2011-07-16
      • 2015-06-19
      • 1970-01-01
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 2016-08-11
      • 2018-03-03
      • 2017-04-26
      相关资源
      最近更新 更多