2

enter image description here

I've read other SO articles relating to UrlGenerationError's which seem to point to singularization or plurization of a word, but I don't think that's the issue here.

It works when I remove from valuations/_form.html.erb:

<%= render "comments/comments" %>
<%= render "comments/form" %>

Submit the _form with :name & :tag_list, readd

<%= render "comments/comments" %>
<%= render "comments/form" %>

and then refresh. What's the deal when nil?

routes

  resources :valuations do
    resources :comments
  end

comments_controller

class CommentsController < ApplicationController
 before_action :load_commentable
  before_action :set_comment, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

 def index
  @comments = @commentable.comments
 end

 def new
  @comment = @commentable.comments.new
 end

 def create
  @comment = @commentable.comments.new(comment_params)
  if @comment.save
   @comment.create_activity :create, owner: current_user 
   redirect_to @commentable, notice: "comment created."
  else
   render :new
  end
 end

 def edit
  @comment = current_user.comments.find(params[:id])
 end

 def update
  @comment = current_user.comments.find(params[:id])
  if @comment.update_attributes(comment_params)
   redirect_to @commentable, notice: "Comment was updated."
  else
   render :edit
  end
 end

 def destroy
  @comment = current_user.comments.find(params[:id])
  @comment.destroy
  @comment.create_activity :destroy, owner: current_user
  redirect_to @commentable, notice: "comment destroyed."
 end

private
  def set_comment
    @comment = Comment.find(params[:id])
  end

 def load_commentable
  resource, id = request.path.split('/')[1, 2]
  @commentable = resource.singularize.classify.constantize.find(id)
 end

 def comment_params
  params.require(:comment).permit(:content, :commentable)
 end
end

valuations_controller

class ValuationsController < ApplicationController
  before_action :set_valuation, only: [:show, :edit, :update, :destroy]
  before_action :logged_in_user, only: [:create, :destroy]

  def index
    if params[:tag]
      @valuations = Valuation.tagged_with(params[:tag])
    else
      @valuations = Valuation.order('RANDOM()')
    end
  end

  def show
    @valuation = Valuation.find(params[:id])
    @commentable = @valuation
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def new
    @valuation = current_user.valuations.build
    @commentable = @valuation
    @comments = @commentable.comments
    @comment = Comment.new
  end

  def edit
  end

  def create
    @valuation = current_user.valuations.build(valuation_params)
    if @valuation.save
      redirect_to @valuation, notice: 'Value was successfully created'
    else
      @feed_items = []
      render 'pages/home'
  end
end

  def update
    if @valuation.update(valuation_params)
      redirect_to @valuation, notice: 'Value was successfully updated'
    else
      render action: 'edit'
  end
end

  def destroy
    @valuation.destroy
    redirect_to valuations_url
  end

private
    def set_valuation
      @valuation = Valuation.find(params[:id])
    end

    def correct_user
      @valuation = current_user.valuations.find_by(id: params[:id])
      redirect_to valuations_path, notice: "Not authorized to edit this valuation" if @valuation.nil?
    end

    def valuation_params
      params.require(:valuation).permit(:name, :private_submit, :tag_list, :content, :commentable, :comment)
    end
end

comments/_form.html.erb

<%= form_for [@commentable, @comment] do |f| %>
  <% if @comment.errors.any? %>
    <div class="error_messages">
      <h2>Please correct the following errors.</h2>
      <ul>
      <% @comment.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

<div class="america">

  <div class="form-group">
    <%= f.text_area :content, rows: 4, class: 'form-control', placeholder: 'Enter Comment' %>
  </div>

  <div class="america2">
  <%= button_tag(type: 'submit', class: "btn") do %>
  <span class="glyphicon glyphicon-plus"></span> Comment
  <% end %>

</div>

<% end %>

enter image description here

Thank you so much for your time.

AnthonyGalli.com
  • 2,796
  • 5
  • 31
  • 80
  • Your actual error stats that the valuation_id parameter is nil. You will need to include that so it knows which valuation the comments are for. – patrick Mar 20 '15 at 01:20
  • Hola @patrick! Where/how do I include that? – AnthonyGalli.com Mar 20 '15 at 01:29
  • Before that, can you explain how this occurs? Like, what's the user's steps. Are they're trying to add a comment to a valuation? – patrick Mar 20 '15 at 01:35
  • The User goes to the _form and they are trying to add a comment to what they are submitting about valuation. I added a picture above of how it should work. – AnthonyGalli.com Mar 20 '15 at 01:40
  • So that picture you added is your `show` action for valuations? – patrick Mar 20 '15 at 02:10
  • Yes sir @patrick. I see I get the error with http://0.0.0.0:3000/valuations/new or http://0.0.0.0:3000/valuations/4/edit. That explains part of my question thanks! – AnthonyGalli.com Mar 20 '15 at 02:14
  • 1
    Well one thing (unrelated) is that your `@valuation = Valuation.find(params[:id])` in your `show` action in `valuations_controller.rb` is redundant as you call a before_action to set the instance variable. – patrick Mar 20 '15 at 02:15
  • Also, can you just try changing the `@commentable` in your `form_for` to `@valuation` and see if that actually works? – patrick Mar 20 '15 at 02:17
  • Nope @patrick error still shows – AnthonyGalli.com Mar 20 '15 at 02:18
  • @patrick I also get an error for ` @comments = @commentable.comments` in valuations_controller new. I don't know if that will shed any more light on the problem: `undefined method "comments" for nil:NilClass` – AnthonyGalli.com Mar 20 '15 at 02:30
  • 1
    Well that's because `@commentable` is nil. Which you've set to `@valuation` which must also be nil. What's the purpose of using the `@commentable` instance variable? is that a tutorial or something you're following? – patrick Mar 20 '15 at 02:32
  • Yea @patrick I followed railscasts: http://railscasts.com/episodes/154-polymorphic-association-revised – AnthonyGalli.com Mar 20 '15 at 17:33

1 Answers1

3

When you have a nested resource like that, the url for creating a comment looks like /valuations/123/comments where 123 is the id of the valuation - without a valuation id this url cannot be generated.

On your Valuations#new page, the valuation (i.e. @commentable) is an unsaved object, so it has no id yet, hence the error about a missing valuation_id. In addition having one form nested within another is invalid html and will lead to odd behaviour. On your show page on the other hand, the valuation does have an id and so things should work as they are.

If you want to create a valuation and its initial comment(s) in one go then you should use accepts_nested_attributes_for and fields_for to add the fields for the comments to your valuation form (There are other ways, but accepts_nested_attributes_for is what is built into rails)

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • The error goes away, but when I click "Add comment" nothing shows up. Do I need to add `_comments_fields.html.erb` & `_form_fields.html.erb` to the comments folder or valuations folder? I did both to play it safe. I'm also going to do this for my other controller views, using the polymorphic comments, so if the fields go in each respective view wouldn't that be a lot of duplication? Thanks so much for your help Frederick! – AnthonyGalli.com Mar 22 '15 at 06:20
  • @Anthony you should be able to share the comments_fields partial much as you share the other ones. Best open a new question to discuss the "add comment" issue – Frederick Cheung Mar 22 '15 at 10:58
  • Good idea Frederick. Here's round 2. http://stackoverflow.com/questions/29197689/how-to-show-polymorphic-comments-fields-partial-in-new. I'd greatly appreciate your help =] – AnthonyGalli.com Mar 22 '15 at 17:45