Reputation: 134
I have a basic blogging site in which I want to allow users to offer 'corrections' to posts (just think of it as a comment). The correction object belongs to a post, which in turn belongs to a user (for which I'm using Devise).
I would like the form to create a new correction to be nested in the page for the post,so I'm just rendering the form in posts/show.html.erb with <% render :template => "corrections/new" %>
. I'm getting a 'undefined method model_name' error from the line form_for line in corrections/new.html.erb though.
Here's the form:
<% form_for [@correction, :url=> user_post_corrections_path(current_user, @post, @correction)], html: { multipart: true} do |f| %>
<div class="field">
<%= f.label :correction %>
<%= f.text_field :correction %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Here's the corrections_controller:
class CorrectionsController < ApplicationController
def new
@post = Post.find(params[:post_id])
@correction = [email protected]
respond_with(@correction)
end
def create
@post = Post.find(params[:post_id])
@correction = [email protected]
if @correction.save
redirect_to user_post_path(current_user, @correction.post_id)
end
end
end
In my routes.rb:
resources :users do
resources :posts do
resources :corrections
end
end
Any help with this would be much appreciated.
Upvotes: 3
Views: 3327
Reputation: 470
There are several issues I can see, first off:
The form is not rendered: The form for should be evaluated not computed so you should use <%= %> tag instead of <%%> tag, so it becomes:
<%= form_for @correction, url: user_post_corrections_path(current_user, @post, @correction), html: { multipart: true} do |f| %>
Second: You are saying form_for @correction, and you said this form is shown in posts/show, this means that the show action for the post should have the following in its controller:
@correction = Correction.new user: current_user, post: @post
This is assuming you are using the @post variable for the post show meaning you have something like
@post = Post.find params[:id]
This line is completely off
@correction = [email protected]
you can just say:
@correction = Correction.new correction_params
@correction.user = current_user
@correction.post = @post
if @correction.save
redirect_to user_post_path(current_user, @correction.post_id)
end
The important part is your show action on the posts controller having the initialization of your @correction object.
Upvotes: 2
Reputation: 11235
This line looks off:
@correction = [email protected]
@post
is an instance variable, not a method on current_user
Did you intend to build a correct with the current user? The following should work:
@post.corrections.build(user: current_user)
If your corrections model has_many :users, through: :posts
, then the following should work:
@post.corrections.build(users: [current_user])
EDIT
The format of your form_for is also incorrect. The url:
key in form_for
doesn't belong in the resource array (the first arg in your form_for)
The following modification should resolve the error, provided user_post_corrections_path
takes :id
, :post_id
, and :correction_id
form_for @correction, url: user_post_corrections_path(current_user, @post, @correction), html: { multipart: true} do |f|
I'd also reduce your routing to two levels of nesting if possible.
Perhaps this is easier?
resources :posts do
resources :corrections
end
end
If it's implied a post belongs to the current_user
then it may not be necessary to have /users
in the route path.
Upvotes: 2