Adam Lazarus
Adam Lazarus

Reputation: 134

rails - undefined method `model_name'

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

Answers (2)

Thresh
Thresh

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

Anthony E
Anthony E

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

Related Questions