我可以在Rails中显示嵌入表单上方的验证错误吗?

时间:2014-10-10 16:59:49

标签: ruby-on-rails forms validation ruby-on-rails-4

不幸的是,我坚持使用我的评论功能。 comment模型与其commentables具有多态关联。这里是模型的草图: model sketch

此外,我有一个publications控制器,当然会显示一些内容,评论以及嵌入式评论表单。另一个草图:

conteroller-view sketch

  1. 使用它的评论表单显示出版物。
  2. 评论表单已提交,数据已发送至create控制器的comment操作。
  3. 不幸的是数据失败验证。
  4. 我现在的问题是,如何在嵌入式表单上方显示验证错误?我知道我可以使用flash来显示错误,但用户会丢失表单数据。

    def create
      @comment = Comment.new(comment_params)
      @comment.commentable = find_commentable
    
      if @comment.save
        redirect_to polymorphic_url(@comment.commentable, anchor: 'comment-' + @comment.id.to_s)
      else
        # What do I need to do here?
      end
    end
    

    如何在@comment中提供publications#show

    我在Rails 4.1上。

2 个答案:

答案 0 :(得分:1)

执行此操作的方法是将以下代码添加到show中的PublicationsController操作中:@comment = Comment.new(或@comment = @publication.comment.new视情况而定)。然后为<%= @comment.errors.full_messages %>的{​​{1}}添加某种show.html.erb类型的代码。最后,Publication操作中的else应为:comments#create

这将显示错误,并允许您的评论表单为render 'publications/show',因此它会显示在评论表单中输入的未验证的内容。

答案 1 :(得分:1)

解决此问题的方法之一是创建一个特殊操作,用于在PublicationsController和其他可注释控制器中创建注释(您可能希望创建一个模块,您将在所有可注释控制器中包含该模块以避免重复并干掉代码。)

我没有时间检查测试Rails应用程序,因此我可能犯了一些拼写错误或其他错误,或者忘记了上面代码中的某些内容。我希望,这个想法仍然清晰。如果您发现错误,请随时编辑。

PublicationsController(和其他可评论的控制器)中:

def add_comment
  # PublicationsController -> Publication
  @commentable_class = self.class.to_s[0..-11].singularize.constantize
  @commentable = @commentable_class.find(params[:commentable_id]) # it is passed by the form, see below
  # set @publication for the publication-specific part of the show view
  instance_variable_set('@'+@comentable_class.to_s.underscore, @commentable) 

  @comment = Comment.new(comment_params.merge(commentable: @commentable)) 

  if @comment.save
    redirect_to action: :show, anchor: 'comment-' + @comment.id.to_s
  else
    render action: :show
  end
end

...

def comment_params
  # don't forget to define comment_params - as in CommentsController, I guess:
  params.require(:comment).permit(:author,:subject,:message)
end

在那些可评论控制器的show操作中,只需执行

def show
  ...
  @commentable_class = self.class.to_s[0..-11].singularize.constantize
  @comment = Comment.new
  @commentable = instance_variable_get('@'+@comentable_class.to_s.underscore)
  ...
end

在评论的show视图中,使用以下表格添加新评论(基于提供的要点):

- if @comment.errors.any?
  %section.errors
    %p= t('errors.templates.body')
    %ul
      - @comment.errors.full_messages.each do |message|
        %li= message
= form_for @comment, url: {controller: @commentable_controller, action: :add_comment} do |form|
  = hidden_field_tag 'commentable_id', @commentable.id
  - unless user_signed_in?
    .row
      .small-12.columns
        = form.label :author
        = form.text_field :author, required: true, pattern: '.{3,30}', title: t('errors.messages.not_in_between', from: 3, to: 30)
  .row
    .small-12.columns
      = form.label :subject
      = form.text_field :subject, pattern: '.{5,80}', title: t('errors.messages.not_in_between', from: 5, to: 80)
  .row
    .small-12.columns
      = form.label :message
      = form.text_area :message, required: true, pattern: '.{30,5000}', title: t('errors.messages.not_in_between', from: 30, to: 5000)
  = form.submit class: 'small radius button right'