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 %>
Thank you so much for your time.
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)
来源:https://stackoverflow.com/questions/29157795/actioncontrollerurlgenerationerror-in-valuationsnew