1

私はレールに比較的慣れていないので、コメントを使って最初のポリモーフィックな関連付けをやめようとしています。

Rails3.2.3を実行しています

編集-コメントを投稿しようとすると、ログに次のエラーが返されます。

Started POST "/comments" for 127.0.0.1 at 2012-05-20 13:17:38 -0700
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓",     "authenticity_token"=>"SOLcF71+WpfNLtpBFpz2qOZVaqcVCHL2AVZWwM2w0C4=", "comment"=>{"text"=>"Test this comment"}, "commit"=>"Create Comment"}
User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 101 LIMIT 1
Completed 500 Internal Server Error in 126ms

NoMethodError (undefined method `Comment' for nil:NilClass):
app/controllers/comments_controller.rb:13:in `create'

私は、SOや他の場所で提供されているさまざまなソリューションを試しましたが、私自身の経験不足のため、以下のジョーダンからの回答も含まれていますが、エラーを解決できませんでした。

トレースはCommentsControllerの13行目を呼び出しており、エラーをマークするために以下の行の後にコメントしました。

class CommentsController < ApplicationController
  def index
    @commentable = find_commentable
    @comments = @commentable.comments
  end

  def new
    @post = Post.find(params[:post_id])
  end

  def create
    @commentable = find_commentable
    @comment = @commentable.comments.build(params[:comment]) #<<<<LINE 13

    if @comment.save
      flash[:notice] = "Successfully created comment."
      redirect_to :id => nil
    else
      render :action => 'new'
    end
  end

  private

  def find_commentable
    params.each do |name, value|
      if name =~ /(.+)_id$/
        return $1.classify.constantize.find(value)
      end
    end

    nil
  end
end

投稿コントローラー:

def show
@post = Post.find(params[:id])

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

コメントテンプレート(ポストショー)

<ul id="comments">
  <% if @comments %>
     <h2>Comments</h2>
         <% @comments.each do |comment| %>
        <li><%= comment.text %></li>
      <% end %>
  <% else %>
       <h2>Comment:</h2>
  <% end %>
</ul>

<%= simple_form_for [@commentable,Comment.new], :html => { :class => 'form-horizontal', :multipart => true } do |f| %>
   <fieldset>
       <%= f.input :text %>
       Upload Photo <%= f.file_field :photo %>
  </fieldset>
  <div class="form-actions">
    <%= f.submit nil, :class => 'btn btn-primary' %>
  </div>
<% end %>

ポストショー:

<p id="notice"><%= notice %></p>
<div class="row">
<div class="span2 offset1">
   <%= image_tag @post.photo.url(:show) %>
</div>
    <div class="span5">
            <h1><%= @post.title %></h1>
            <p><%= @post.index_text.html_safe %></p>
           <p><%= @post.show_text.html_safe %></p>
            <%= render "comments/comment" %>
            <%= render "comments/form" %>
            <% if can? :update, @course %>
                <%= link_to 'Edit Post', edit_post_path(@post), :class => 'btn btn-mini' %>
                <%= link_to 'Delete Post', @post, 
                                    confirm: 'Are you sure?', 
                                    method: :delete, 
                                    :class => 'btn btn-mini' %>
                 <%= link_to 'New Post', new_post_path, :class => 'btn btn-mini' %>
            <% end %>
     </div>

<nav class="span2 offset1">
    <ul class="well">
        <li>Category 1</li>
        <li>Category 2</li>
    </ul>
</nav>
</div>
<div class="row offset2">
    <%= link_to 'Back to Posts', posts_path, :class => 'btn btn-mini' %>
</div>

ルート:

  resources :posts, :has_many => :comments
  resources :comments

より多くの経験を持つ誰かが解決できることはおそらく明らかなことです。何か頭に浮かんだことがあれば教えてください。ブライアン

4

3 に答える 3

1

問題はそれ@commentableがであるということですnil、それはそれCommentsController#find_commentableが戻っていることを意味しnilます。あなたの正規表現は健全だと思います。つまり、次の2つのいずれかが発生していることを意味しfind_commentableます。

  1. params正規表現に一致するキーはありません。
  2. 正規表現は一致していますが、結果のテーブルにIDがのレコードはありませんvalue

データベース内のレコードを調べて、通常どおりにこれをデバッグし、params期待どおりに見えることを確認します。

于 2012-05-20T15:25:57.400 に答える
1

問題はfind_commentableメソッドです。

CommentsController#createに渡されるパラメータは次のとおりです。

Started POST "/comments" for 127.0.0.1 at 2012-05-20 13:17:38 -0700
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓",     "authenticity_token"=>"SOLcF71+WpfNLtpBFpz2qOZVaqcVCHL2AVZWwM2w0C4=", "comment"=>{"text"=>"Test this comment"}, "commit"=>"Create Comment"}

これがあなたのCommentsController#createです:

def create
  @commentable = find_commentable
  @comment = @commentable.comments.build(params[:comment]) #<<<<LINE 13


def find_commentable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end

  nil
end

ご覧のとおり、find_commentableは、適切なクラス(comments_idの場合はComment)を検索するために使用するxx_id(たとえば、comments_id)のようなパラメーターを期待します。それ以外の場合はnilを返します。ここで分類と定数化を参照してください。

パラメータにはそのようなパラメータは含まれていません。したがって、常にnilオブジェクトを取得します。

find_commentableにはいくつかの手直しが必要です。ネストされたフィールドの場合、次のような式にする必要があると思います

/(.+)_attributes$/ 

それ以外の

/(.+)_id$/. 

そして、あなたは持っている必要があります

:accepts_nested_attributes_for :commentable 

コメントモデルクラスで。

于 2012-05-21T06:18:29.180 に答える
0

上記の両方の答えを試しましたが、問題は解決しませんでした。

私は次の解決策を提案した友人と相談することになりました。これは、元の試みよりもエレガントで、読みやすいためです(後で、私または他の誰かがコードに戻る必要がある場合)。

def find_commentable
  if params[:post_id]
    Post.find(params[:post_id])
  #elsif params[:other_id]
  #  Other.find(params[:other_id])
  else
    # error out?
  end
end

コメントアウトされたセクションでは、他のアソシエーションを起動して実行すると、それらを参照します。

于 2012-05-22T16:25:48.747 に答える