ruby-on-railsnested-formsform-fornested-form-for

Undefined Method in Form_For Helper


I have a post model that belongs_to a category model. The post resources are nested under the category resources. I'm building out a form_for @post to create a new post. However, I'm getting the following error:

undefined method 'posts_path' for #<#<Class:0x007fd54ba33540>:0x007fd54c8e57c8>

According to my routes, it should be pointing to the new_category_post_path but I'm not sure why it's not. I tried the solution proposed here because it's very similar to my situation but to no avail. Any ideas?

routes.rb:

resources :categories do
  resources :posts
end

app/models/category.rb and post.rb:

class Category < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :category
end

app/controllers/posts_controller.rb:

class PostsController < ApplicationController    
  def new
    @category = Category.find(params[:category_id])
    @post = @category.posts.new
  end
end

views/posts/new.html.erb:

<%= form_for @post do |f| %>
  <%=f.text_field :title, placeholder: 'Title...' %>
  <%=f.text_area :content %>
  <%=f.submit 'Create post' %>
<% end %>

rake routes:

            Prefix Verb   URI Pattern                                       Controller#Action
    category_posts GET    /categories/:category_id/posts(.:format)          posts#index
                   POST   /categories/:category_id/posts(.:format)          posts#create
 new_category_post GET    /categories/:category_id/posts/new(.:format)      posts#new
edit_category_post GET    /categories/:category_id/posts/:id/edit(.:format) posts#edit
     category_post GET    /categories/:category_id/posts/:id(.:format)      posts#show
                   PATCH  /categories/:category_id/posts/:id(.:format)      posts#update
                   PUT    /categories/:category_id/posts/:id(.:format)      posts#update
                   DELETE /categories/:category_id/posts/:id(.:format)      posts#destroy
        categories GET    /categories(.:format)                             categories#index
                   POST   /categories(.:format)                             categories#create
      new_category GET    /categories/new(.:format)                         categories#new
     edit_category GET    /categories/:id/edit(.:format)                    categories#edit
          category GET    /categories/:id(.:format)                         categories#show
                   PATCH  /categories/:id(.:format)                         categories#update
                   PUT    /categories/:id(.:format)                         categories#update
                   DELETE /categories/:id(.:format)                         categories#destroy
              root GET    /                                                 categories#index

Solution

  • If you want to nest your resources, then you need to make sure the URL which is generated in the form_for helper knows how to do that correctly. In this case, you need to pass it 2 objects, the post object, and the category object. The location is first, the new object is second in the array, so your form for will look more like:

    <%= form_for [@category,@post] do |f| %>
      <%=f.text_field :title, placeholder: 'Title...' %>
      <%=f.text_area :content %>
      <%=f.submit 'Create post' %>
    <% end %>