gpt4 book ai didi

ruby-on-rails - 通过重定向进行Rails验证

转载 作者:行者123 更新时间:2023-12-04 05:00:09 26 4
gpt4 key购买 nike

我正在尝试用rails编写的beast论坛,并将其用作我一直面临的问题的示例。

该论坛有一个主题/显示操作,并在底部带有一个窗体的 View ,以在该主题中创建新帖子。

提交表单将转至帖子/创建,如果验证通过,则重定向回主题/显示,并且工作正常,但是,如果验证失败(省略正文字段),则将您重定向到相同的主题/显示,并返回到表单,没有验证错误...通常,如果验证失败,您将使用render:action => new进行任何操作。

验证是否在重定向中丢失了,使其正常工作的最佳方法是什么?

参见下面的代码:

PostsController.rb

  def create
@post = current_user.reply @topic, params[:post][:body]

respond_to do |format|
if @post.new_record?
format.html { redirect_to forum_topic_path(@forum, @topic) }
format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
else
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to(forum_topic_post_path(@forum, @topic, @post, :anchor => dom_id(@post))) }
format.xml { render :xml => @post, :status => :created, :location => forum_topic_post_url(@forum, @topic, @post) }
end
end
end

TopicsController.rb
  def show
respond_to do |format|
format.html do
if logged_in?
current_user.seen!
(session[:topics] ||= {})[@topic.id] = Time.now.utc
end
@topic.hit! unless logged_in? && @topic.user_id == current_user.id
@posts = @topic.posts.paginate :page => current_page
@post = Post.new
end
format.xml { render :xml => @topic }
end
end

主题/节目 View
  <% form_for :post, :url => forum_topic_posts_path(@forum, @topic, :page => @topic.last_page) do |f| %>

<%= f.error_messages %>

<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td rowspan="2" width="70%">
<%= f.text_area :body, :rows => 8 %>
</td>
<td valign="top">
<%= render :partial => "posts/formatting" %>
</td>
</tr>
<tr>
<td valign="bottom" style="padding-bottom:15px;">
<%= submit_tag I18n.t('txt.views_topics.save_reply', :default => 'Save reply') %>
</td>
</tr>
</table>
<% end %>

非常感谢。

最佳答案

我认为您在这里有两个问题。

  • 通过重定向
  • 保持验证错误
  • 重新填充表单字段,因此用户不必再次输入所有信息。

  • 这两个东西都是相连的。

    验证错误通常通过对对象起作用的error_msg_for方法显示。通常由 Controller 作为无法保存的对象的实例变量提供。相同的实例变量用于重新填充表格。

    在重定向期间, Controller 通常将使用params哈希实例化实例变量。因此,用于确定保存失败原因的所有信息都将丢失。正常资源将在保存失败时呈现,并在成功时重定向,这会导致两件事发生。
  • 该对象的实例传递给error_msg_,用于创建该统一错误框。
  • 对象的实例用于填充表单的字段,从而使您的用户仅编辑必要的内容。

  • 我不太了解Beast,所以我不确定创建线程的表单是否为事件记录模型。但是以下内容将为您提供一个解决问题的方法。这将涉及修改您的Beast插件的本地副本,因此,如果您使用的是一种工具来使其保持更新,则所做的更改可能会丢失。

    我一直在使用以下以下方法来获取您的验证问题。假设您所讨论的表单基于nmodel,则它们应该为您提供重新填充表单所需的一切。

    本质上,您可以使用clone_with_errors将对象的浅拷贝和错误存储在闪存哈希中。您必须使用浅拷贝,否则在显示具有多个关联的记录的错误时会遇到问题。

    然后,我使用my_error_msg_for,它采用与标准error_msg_for相同的选项来构建错误消息html。我之所以写它,是因为出于某种原因,标准的error_msg_for方法不适用于散列中存储的对象。它几乎与error_msg_for的官方原始版本相同,该版本令人不安。

    /app/controllers/examples_controller.rb
    class ExamplesController < ApplicationController
    def update
    ...

    if @example.save
    regular action
    else
    flash[:errors] = clone_with_errors(@example)
    respond_to do |format|
    format.html redirect_to(@example)
    end
    end
    end

    /app/views/examples/show.html.erb
    <div id="error">
    <% if flash[:errors] && !flash[:errors].empty? then -%>

    <p ><%= my_error_msg_for flash[:errors] %></p>

    <% end -%>
    </div>
    ...

    这是使它们全部工作所需的代码。

    application_controller.rb
     def clone_with_errors(object)
    clone = object.clone
    object.errors.each{|field,msg| clone.errors.add_to_base(msg)}
    return clone
    end

    application_helper.rb
     def _error_msg(*params)

    options = params.extract_options!.symbolize_keys
    if object = options.delete(:object)
    objects = [object].flatten
    else
    objects = params.collect {|object_name| instance_variable_get("@#{object_name}") }.compact
    end
    count = objects.inject(0) {|sum, this| sum + this.errors.count }
    unless count.zero?
    html = {}
    [:id, :class].each do |key|
    if options.include?(key)
    value = options[key]
    html[key] = value unless value.blank?
    else
    html[key] = 'errorExplanation'
    end
    end
    options[:object_name] ||= params.first
    options[:header_message] = "#{pluralize(count, 'error')} prohibited this #{options[:object_name].to_s.gsub('_', ' ')} from being saved" unless options.include?(:header_message) && !options[:header_messag].nil?
    options[:message] ||= 'There were problems with the following fields:' unless options.include?(:message) && !options[:message].nil?
    error_messages = objects.sum {|this| this.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join

    contents = ''
    contents << content_tag(options[:header_tag] || :h2, options[:header_message]) unless options[:header_message].blank?
    contents << content_tag(:p, options[:message]) unless options[:message].blank?
    contents << content_tag(:ul, error_messages)

    content_tag(:div, contents, html)
    else
    ''
    end

    end

    def my_error_msg_for(params)
    _error_msg_test :object_name => params[:object].class.name.gsub(/([a-z])([A-Z])/,'\1 \2').gsub(/_/, " "),
    :object => params[:object], :header_message => params[:header_message], :message => params[:message]
    end

    关于ruby-on-rails - 通过重定向进行Rails验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1536428/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com