How to Build a Forum with Jumpstart Pro
Hey Guys,
I'm following along with the How to Build a Forum with Jumpstart Pro video (https://www.youtube.com/watch?v=ZSom4V-nYxA&t=903s) and I am running into the error "The action 'create' could not be found for PostsController" when trying to reply to a discussion. Here are my files:
posts_controller.rb
class PostsController < ApplicationController
before_action :set_discussion
before_action :set_post, only[:edit, :update, :destroy]
def create
@post = @discussion.posts.new(post_params)
@post.user = current_user
if @post.save
redirect_to discussion_path(@discussion, anchor: @post.id)
else
redirect_to @discussion, alert: @post.errors.full_messages.first
end
end
def edit
end
def update
if @post.update(post_params)
redirect_to discussion_path(@discussion, anchor: @post.id)
else
redirect_to @discussion, alert: @post.errors.full_messages.first
end
end
def destroy
@post.destroy
redirect_to @discussion
end
private
def set_discussion
@discussion = Discussion.find(params[:discussion_id])
end
def set_post
@post = @discussion.posts.find_by!(id: params[:id], user: current_user)
end
def post_params
params.require(:post).permit(:body)
end
end
_post.html.erb
<div id="<%= dom_id(post) %>" class="flex pb-6 border-b mb-6 group">
<div class="mr-6">
<%= image_tag avatar_url_for(post.user), class: "rounded-full", height: 40, width: 40 %>
</div>
<div class="flex-1">
<div class="mb-4">
<span class="font-semibold"><%= post.user.name %></span>
<span class> <%= link_to local_time_ago(post.created_at), discussion_path(@discussion, anchor: post.id), class: "ml-1 hover:underline text-gray-700" %></span>
<% if user_signed_in? && current_user == post.user %>
<span class="text-gray-600">-</span> <%= link_to "Edit", edit_discussion_post_path(@discussion, post), class: "ml-1 hover:underline text-gray-700" %>
<% end %>
</div>
<div>
<%= post.body %>
</div>
</div>
</div>
edit.html.erb
<div class="container mx-auto my-8 px-4 max-w-3xl bg-white shadow p-8">
<h1 class="h2 mb-6">Editing Post</h1>
<%= form_with model: [@discussion, @post], class: "flex-1" do |form| %>
<div class="form-group">
<%= form.rich_text_area :body, data: { controller: "mentions", target: "mentions.field" } %>
</div>
<div class="form-group flex justify-between">
<%= link_to "Delete", [@discussion, @post], method: :delete, class: "btn btn-link text-red-700", data: { remote: true, confirm: "Are you sure?" } %>
<div>
<%= link_to "Cancel", @discussion, class: "btn btn-link" %>
<%= form.submit "Save Changes", class: "btn btn-tertiary", data: { disable_with: "Saving..." } %>
</div>
</div>
<% end %>
</div>
discussion_controller.rb
class DiscussionsController < ApplicationController
before_action :authenticate_user!, except: [:index, :show]
before_action :set_discussion, only: [:show, :edit, :update, :destroy]
# GET /discussions
def index
@pagy, @discussions = pagy(Discussion.all)
end
# GET /discussions/1
def show
end
# GET /discussions/new
def new
@discussion = Discussion.new
@discussion.posts.new
end
# GET /discussions/1/edit
def edit
end
# POST /discussions
def create
@discussion = current_user.discussions.new(discussion_params)
@discussion.posts.each{ |post| post.user = current_user }
if @discussion.save
redirect_to @discussion, notice: 'Discussion was successfully created.'
else
render :new
end
end
# PATCH/PUT /discussions/1
def update
if @discussion.update(discussion_params)
redirect_to @discussion, notice: 'Discussion was successfully updated.'
else
render :edit
end
end
# DELETE /discussions/1
def destroy
@discussion.destroy
redirect_to discussions_url, notice: 'Discussion was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_discussion
@discussion = Discussion.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def discussion_params
params.require(:discussion).permit(:user_id, :title, posts_attributes: [:body])
end
end
Here are my routes:
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
Rails.application.routes.draw do
resources :discussions do
resources :posts
end
# Jumpstart views
if Rails.env.development? || Rails.env.test?
mount Jumpstart::Engine, at: '/jumpstart'
mount LetterOpenerWeb::Engine, at: "/letter_opener"
end
# Administrate
authenticated :user, lambda { |u| u.admin? } do
namespace :admin do
if defined?(Sidekiq)
require 'sidekiq/web'
mount Sidekiq::Web => '/sidekiq'
end
resources :announcements
resources :users
namespace :user do
resources :connected_accounts
end
resources :teams
resources :team_members
resources :plans
namespace :pay do
resources :charges
resources :subscriptions
end
root to: "dashboard#show"
end
end
# User account
devise_for :users,
controllers: {
masquerades: 'jumpstart/masquerades',
omniauth_callbacks: 'users/omniauth_callbacks',
registrations: 'users/registrations',
}
resources :announcements, only: [:index]
resources :teams do
member do
patch :switch
end
resources :team_members, path: :members
end
# Payments
resource :card
resource :subscription do
patch :info
patch :resume
end
resources :charges
namespace :account do
resource :password
end
resources :users
namespace :user, module: :users do
resources :connected_accounts
end
scope controller: :static do
get :about
get :terms
get :privacy
get :pricing
end
authenticated :user do
root to: "dashboard#show", as: :user_root
end
# Public marketing homepage
root to: "static#index"
end
Here is what it's showing:
Prefix Verb URI Pattern Controller#Action
discussion_posts GET /discussions/:discussion_id/posts(.:format) posts#index
POST /discussions/:discussion_id/posts(.:format) posts#create
new_discussion_post GET /discussions/:discussion_id/posts/new(.:format) posts#new
edit_discussion_post GET /discussions/:discussion_id/posts/:id/edit(.:format) posts#edit
discussion_post GET /discussions/:discussion_id/posts/:id(.:format) posts#show
PATCH /discussions/:discussion_id/posts/:id(.:format) posts#update
PUT /discussions/:discussion_id/posts/:id(.:format) posts#update
DELETE /discussions/:discussion_id/posts/:id(.:format) posts#destroy