2016-11-27 63 views
0

我跟着getting started tutorial for Rails這是很好的大部分,但缺乏一些細節的時候遇到了相應的模型(評論):如何從Rails的教程地址關聯模型的缺點

  1. 有沒有驗證 - 很容易添加,但是我不確定如何顯示驗證失敗時的錯誤消息。
  2. 使用@article.comments.build這樣就可以顯示有效評論表單「創建」,在那屆另一個評論,所以如果你通過所有評論迭代,有好多是因爲有一個額外的空白之一。這只是一個巧合,指南列出了之前的這行代碼被執行,因此沒有遇到問題。

雖然我嘗試了1(這將在下面詳述),但我不知道如何去解決2. - 它可能屬於它自己的問題,但我甚至不知道如何命名它。

嘗試在審定/錯誤顯示

我想基本上採用同樣的策略與文章顯示錯誤信息,再次進行了點評。我知道會有一些額外的複雜性,但我試圖從邏輯上進行導航。這是我改變了:

應用程序/模型/ comments.rb

class Comment < ApplicationRecord 
    belongs_to :post 

    validates :commenter, presence: true 
    validates :body, presence: true 
end 

應用程序/控制器/ comments_controller.rb

class CommentsController < ApplicationController 
    def create 
    @article = Post.find(params[:article_id]) 
    @comment = @article.comments.new(comment_params) 

    if @comment.save 
     redirect_to article_path(@article) 
    else 
     render 'articles/show' 
    end 
    end 

    def destroy 
    ... 

應用程序/意見/評論/ _form.html.erb

<%= form_for([@article, @article.comments.build]) do |f| %> 
    <% if self.instance_variable_defined?('@comment') and @comment.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@comment.errors.count, 'error') %> occurred:</h2> 
     <ul> 
     <% @comment.errors.full_messages.each do |msg| %> 
      <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

    <p> 
    <%= f.label :commenter, 'Your Name' %> 
    ... 

雖然這成功地顯示錯誤消息,下面的問題出現了:

  1. 因爲它使用了render而不是重定向,所以用戶最終得到的URL通常不能提供GET請求(即,/posts/1/comments) - 這很奇怪,因爲如果頁面再次載入,它將會是404。我不能使用重定向,因爲那麼嘗試創建註釋(帶有錯誤消息)將會丟失。
  2. 大概是因爲@article.comments.new之前已經呈現執行時,作爲同樣的問題,其是在2以上(關於@article.comments.build)所述發生:顯示一個空白註釋。

所以這就是我卡住了。這些都是非常基本的問題 - 沒有它們,系統就不會完整,但我爲什麼會遇到問題而迷失了方向。

如何顯示這些錯誤,同時避免上述問題?

回答

1

通過@ evedovelli的使用flash的啓發,但解決它了(在這個問題的答案的評論提到的)的問題,我最終使用:

  • flash[:comment_errors] = @comment.errors.full_messages自己跨越重定向通信的錯誤消息。我無法刷新@comment@comment.errors,因爲它們以散列而不是原始對象的實例結束,因此失去了其有用的方法,而full_messages僅僅是一個數組,因此完整地進行了通信。
  • form_for([@post, Comment.new]) do |f|(而不是@post.comments.new/build)。該新評論不會立即鏈接到@post,因此不會出現在@post.comments.all中。雖然表單仍然有效 - 提交內容僅在該帖子下創建評論。不過,我覺得這仍然只是避免了真正的問題:如果我因爲某種原因嘗試循環所有評論,那麼這個新的,未保存的評論將再次被發現。

    那麼新的,未保存的評論將被再次發現

    我才發現自己遇到了一些潛在的搜索字詞跌跌撞撞(其中我不能:

編寫form_for部分後之前找不到這個問題的話)!所以我搜索rails collection get saved only,導致rails activerecord get persisted,並具有以下有用的方法上來:

這些可以用來妥善解決第二個問題:由專門忽略記錄哪些尚未保存,只有在適當的情況下。太好了!

1

您的顯示錯誤的解決方案是正確的。當你渲染articles/show而不是重定向時,就像你想的那樣,你最終在/posts/:id/comments中,因爲這是你剛剛調用的HTTP方法POST的當前路徑。

若要顯示錯誤和重定向到new路徑,你可以進行一些修改代碼:

1)在創建操作:

if @comment.save 
    flash[:comment] = nil 
    redirect_to article_path(@article) 
else 
    flash[:comment] = @comment 
    redirect_to article_path(@article) 
end 

2)在演出中的文章操作:

@comment = flash[:comment] || @article.comments.build 

3)在所述製品放映視圖,替換爲form_for行:

<%= form_for([@article, @comment]) do |f| %> 

然後你可以,用戶代碼,顯示錯誤:

<% if self.instance_variable_defined?('@comment') and @comment.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@comment.errors.count, 'error') %> occurred:</h2> 
     <ul> 
     <% @comment.errors.full_messages.each do |msg| %> 
      <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

該解決方案可以解決你跑進以及第二個問題。

如果我誤解了你的問題,請讓我知道並幫助你。

+1

我試過這個,但它不起作用。問題2仍然存在,它實際上不再顯示錯誤消息。請注意,我必須更改'@comment = flash [:comment] || ...'如果閃光[:評論] @comment = Comment.new(flash [:comment])否則...'因爲它根本不能工作 - 評論只是一個散列而不是'Comment'的一個實例。 –

+0

我懷疑我可以簡單地'閃爍'完整的錯誤信息,而不是整個評論。但是有沒有更多的「軌道」方法呢? –