adding my comment system to the index page - ruby-on-rails

i have a comment system associated to a shipment model in my app where a user can have many shipments and a shipment can have many comments.
Everything is working perfectly the only problem is that i want my whole comment system to be shown in the index page of my model currently it is in the show page.
when i try to put it on the index page i get an error:
undefined method `comments' for nil:NilClass
My Controllers
shipment_controller.rb
class ShipmentsController < ApplicationController
before_action :set_shipment, only: [:show, :edit, :update, :destroy]
before_action :authenticate_user!
# GET /shipments
# GET /shipments.json
def index
#shipments = Shipment.all
end
# GET /shipments/1
# GET /shipments/1.json
def show
#comments = Comment.where(shipment_id: #shipment)
end
# GET /shipments/new
def new
#shipment = Shipment.new
end
# GET /shipments/1/edit
def edit
end
# POST /shipments
# POST /shipments.json
def create
#shipment = current_user.shipments.new(shipment_params)
respond_to do |format|
if #shipment.save
format.html { redirect_to #shipment, notice: 'Shipment was successfully created.' }
format.json { render :show, status: :created, location: #shipment }
else
format.html { render :new }
format.json { render json: #shipment.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /shipments/1
# PATCH/PUT /shipments/1.json
def update
respond_to do |format|
if #shipment.update(shipment_params)
format.html { redirect_to #shipment, notice: 'Shipment was successfully updated.' }
format.json { render :show, status: :ok, location: #shipment }
else
format.html { render :edit }
format.json { render json: #shipment.errors, status: :unprocessable_entity }
end
end
end
# DELETE /shipments/1
# DELETE /shipments/1.json
def destroy
#shipment.destroy
respond_to do |format|
format.html { redirect_to shipments_url, notice: 'Shipment was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_shipment
#shipment = Shipment.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def shipment_params
params.require(:shipment).permit(:name, :description, :from, :to, :date, :pay)
end
end
comments_controller.rb
class CommentsController < ApplicationController
before_action :authenticate_user!
def create
#shipment = Shipment.find(params[:shipment_id])
#comment = Comment.create(params[:comment].permit(:content))
#comment.user_id = current_user.id
#comment.shipment_id = #shipment.id
if #comment.save
redirect_to shipment_path(#shipment)
else
render 'new'
end
end
end
My routes
Rails.application.routes.draw do
devise_for :users, :controllers => {:registrations => "registrations"}
resources :shipments do
resources :comments
end
root 'shipments#index'
end
Shipment View
show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong><%= current_user.full_name %></strong>
</p>
<p>
<strong>Description:</strong>
<%= #shipment.description %>
</p>
<p>
<strong>From:</strong>
<%= #shipment.from %>
</p>
<p>
<strong>To:</strong>
<%= #shipment.to %>
</p>
<p>
<strong>Date:</strong>
<%= #shipment.date %>
</p>
<p>
<strong>Pay:</strong>
<%= #shipment.pay %>
</p>
<div id="comments">
<h2 class="comment_count">
<%= pluralize(#shipment.comments.count, "comment") %>
</h2>
<% #comments.each do |comment| %>
<div class="comment">
<p class="full_name">
<%= comment.user.full_name %>
</p>
<p class="content">
<%= comment.content %>
</p>
</div>
<% end %>
<%= render "comments/form" %>
</div>
<%= link_to 'Edit', edit_shipment_path(#shipment) %> |
<%= link_to 'Back', shipments_path %>
Comments View render
_form.html.erb
<%= simple_form_for([#shipment, #shipment.comments.build]) do |f| %>
<%= f.input :content, label: "Reply to thread" %>
<%= f.button :submit, class: "button" %>
<% end %>
index.html.erb without comments
<h1>Listing Shipments</h1>
<%= link_to "Post a new Shipment", new_shipment_path, class: "btn btn-success" %>
<% #shipments.each do |shipment| %>
<div class="shipment">
<h3><strong><%= shipment.user.full_name%></strong></h3>
<h5><strong>DESCRIPTION: </strong><%= shipment.description %></h5>
<div class="meta">
<%= link_to time_ago_in_words(shipment.created_at) + " ago" %> |
<%= link_to "show", shipment %>
<span class="admin">
| <%= link_to "Edit", edit_shipment_path(shipment) %> |
<%= link_to "Delete", shipment, method: :delete, data: { confirm: "Hey! Are you sure! You wanna delete this shipment??"} %>
</span>
</div>
</div>
<% end %>
index.html.erb with comment system
<h1>Listing Shipments</h1>
<%= link_to "Post a new Shipment", new_shipment_path, class: "btn btn-success" %>
<% #shipments.each do |shipment| %>
<div class="shipment">
<h3><strong><%= shipment.user.full_name%></strong></h3>
<h5><strong>DESCRIPTION: </strong><%= shipment.description %></h5>
<div class="meta">
<%= link_to time_ago_in_words(shipment.created_at) + " ago" %> |
<%= link_to "show", shipment %>
<span class="admin">
| <%= link_to "Edit", edit_shipment_path(shipment) %> |
<%= link_to "Delete", shipment, method: :delete, data: { confirm: "Hey! Are you sure! You wanna delete this shipment??"} %>
</span>
</div>
</div>
<div id="comments">
<h2 class="comment_count">
<%= pluralize(#shipment.comments.count, "comment") %>
</h2>
<% #comments.each do |comment| %>
<div class="comment">
<p class="full_name">
<%= comment.user.full_name %>
</p>
<p class="content">
<%= comment.content %>
</p>
</div>
<% end %>
<%= render "comments/form" %>
<% end %>
After Pavan's Answer
Error
ActiveRecord::RecordNotFound (Couldn't find Shipment with 'id'=):
app/controllers/shipments_controller.rb:9:in `index'
Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.0ms)
Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.0ms)
Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb
(1.0ms)
Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/actionpack-4.2.3
/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within re
scues/layout (36.0ms)
Rendered C:/RailsInstaller/Ruby2.0.0/lib/ruby/gems/2.0.0/gems/web-console-2.2.
1/lib/web_console/templates/_markup.html.erb (1.0ms)

You've got an ivar #comments that doesn't appear to be defined...Try #shipment.comments.each

I want my whole comment system to be shown in the index page of my
model currently it is in the show page
You need to loop through #shipments in the index view like below
<% #shipments.each do |shipment| %>
<% shipment.comments.each do |comment| %>
----rest of the code---
<% end %>
<% end %>
Update:
You are getting the error here in this line <%= pluralize(#shipment.comments.count, "comment") %>. You just need to change it to
<%= pluralize(shipment.comments.count, "comment") %>
And you need to modify the comments iteration part like I said above.

Related

Rails: param is missing or the value is empty: admin

I am working on a Rails project and I am using namespacing for the models and controllers. That is the child models are put in a directory called user and the controllers are put in a directory called users.
For more clarity, I have a user model that has child admin and student models using Single Table Inheritance (STI). These child models inherit all the attributes of the parent model and can individually define their validations and methods and are placed in a directory called user.
I also have admins_controller and students_controller that use the admin model and the student model respectively. These controllers are placed in a directory called users.
Here's my code;
User model:
class User < ApplicationRecord
has_secure_password
end
Admin model:
class User::Admin < User
end
Student model:
class User::Student < User
end
Admin Controller:
class Users::AdminsController < ApplicationController
before_action :set_admin, only: [:show, :edit, :update, :destroy]
# GET /admins
# GET /admins.json
def index
#admins = User::Admin.all
end
# GET /admins/1
# GET /admins/1.json
def show
end
# GET /admins/new
def new
#admin = User::Admin.new
end
# GET /admins/1/edit
def edit
end
# POST /admins
# POST /admins.json
def create
#admin = User::Admin.new(admin_params)
respond_to do |format|
if #admin.save
format.html { redirect_to users_admin_path(#admin), notice: 'Admin was successfully created.' }
format.json { render :show, status: :created, location: users_admin_path(#admin) }
else
format.html { render :new }
format.json { render json: #admin.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /admins/1
# PATCH/PUT /admins/1.json
def update
respond_to do |format|
if #admin.update(admin_params)
format.html { redirect_to users_admin_path(#admin), notice: 'Admin was successfully updated.' }
format.json { render :show, status: :ok, location: users_admin_path(#admin) }
else
format.html { render :edit }
format.json { render json: #admin.errors, status: :unprocessable_entity }
end
end
end
# DELETE /admins/1
# DELETE /admins/1.json
def destroy
#admin.destroy
respond_to do |format|
format.html { redirect_to users_admins_url, notice: 'Admin was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_admin
#admin = User::Admin.find(params[:id])
end
# Only allow a list of trusted parameters through.
def admin_params
params.require(:admin).permit(:email, :password, :role)
end
end
Routes:
Rails.application.routes.draw do
namespace :users do
resources :admins
resources :students
end
end
index.html.erb:
<p id="notice"><%= notice %></p>
<h1>Admins</h1>
<table>
<thead>
<tr>
<th>Email</th>
<th>Password</th>
<th>Role</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #admins.each do |admin| %>
<tr>
<td><%= admin.email %></td>
<td><%= admin.password %></td>
<td><%= admin.role %></td>
<td><%= link_to 'Show', users_admin_path(admin) %></td>
<td><%= link_to 'Edit', edit_users_admin_path(admin) %></td>
<td><%= link_to 'Destroy', users_admin_path(admin), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Admin', new_users_admin_path %>
show.html.erb:
<p id="notice"><%= notice %></p>
<p>
<strong>Email:</strong>
<%= #admin.email %>
</p>
<p>
<strong>Password:</strong>
<%= #admin.password %>
</p>
<p>
<strong>Role:</strong>
<%= #admin.role %>
</p>
<%= link_to 'Edit', edit_users_admin_path(#admin) %> |
<%= link_to 'Back', users_admins_path %>
_form.html.erb:
<% if #admin.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#admin.errors.count, "error") %> prohibited this admin from being saved:</h2>
<ul>
<% #admin.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :email %>
<%= form.text_field :email %>
</div>
<div class="field">
<%= form.label :password %>
<%= form.text_field :password %>
</div>
<div class="field">
<%= form.label :role %>
<%= form.text_field :role %>
</div>
<div class="actions">
<%= form.submit %>
</div>
new.html.erb:
<h1>New Admin</h1>
<%= form_with(model: #admin, url: users_admins_path, local: true) do |form| %>
<%= render partial: 'form', admin: #admin, locals: { form: form } %>
<% end %>
<%= link_to 'Back', users_admins_path %>
edit.html.erb:
<h1>Editing Admin</h1>
<%= form_with(model: #admin, url: users_admin_path(#admin), local: true) do |form| %>
<%= render partial: 'form', admin: #admin, locals: { form: form } %>
<% end %>
<%= link_to 'Show', users_admin_path %> |
<%= link_to 'Back', users_admins_path %>
However, when I try creating a new admin or updating an already existing admin, I get the error:
param is missing or the value is empty: admin
I have tried to debug the cause of the issue, but no luck yet. Any form of help will be highly appreciated.
I finally figured it out after careful examination of my logs.
Here's how I solved it:
I examined the request parameters of the create action and I realized that it was of this format:
{"authenticity_token"=>"qJWlHz7Z5myTH3dwNIjjSOzRDY7JN+LoovaG+8dMBnGFRWImJKlWp8cgF7kwTqJXIxqU2fGVkqW9nhOAJ8vFIg==",
"user_admin"=>{"email"=>"promise#gmail.com", "password"=>"[FILTERED]", "role"=>""},
"commit"=>"Create Admin"}
So the request parameters have a hash key of user_admin with values email, password and role, whereas I was passing the admin hash key in my admins_controller.
All I had to do was to modify the admins_params private method in my admins_controller:
From this:
def admin_params
params.require(:admin).permit(:email, :password, :role)
end
To this:
def admin_params
params.require(:user_admin).permit(:email, :password, :role)
end
and that solved the issue.
If you have such an issue, always endeavour to inspect your request parameters in your logs or your application trace. That will give you a lot of information that will help you to resolve the issue.
That's all.
I hope this helps

Rails: Undefined local variable or method `form' in rails 4.1

In my _form partial I render another partial like below
<%= render :partial => 'test', :object => #application.type, \
:locals => {:form => form, \
:application_type => "application[type]"} %>
When I try to load the form I get this error
undefined local variable or method `form' for #<#<Class:0x6daf2c8>:0x8dd3c80>
My test partial
<%= fields_for application_type, application do |application_f| %>
<div>
<div>
<%= application_f.label :uni_id, "University" %>
<%= application_f.collection_select :uni_id, #unis, :id, :check, {:include_blank => true} %>
</div>
</div>
<div>
<% end %>
I recently updated to rails 4.1 from 3.2. It was working before but now it shows error. I guess it is syntax error but could not solve it.
Maybe you need to replace something like this, in your top-level template:
<%= render partial: "form", form: form %>
or like this:
<%= render partial: "form", object: form %>
with something like this (the locals parameter is required now)
<%= render partial: "form", locals: { form: form } %>
Quite a few errors:
<%= render partial: 'test', locals: {form: form }, object: #application %>
<%= form.fields_for application.type, application do |application_f| %>
<div>
<div>
<%= application_f.label :uni_id, "University" %>
<%= application_f.collection_select :uni_id, #unis, :id, :check, {:include_blank => true} %>
</div>
</div>
</div>
<% end %>
This should provide the correct syntax for you.
The error is down to the form variable not being populated. This seems to be from the <%= render call. Without context, the best fix I can give is how it should look:
<%= form_for #variable do |form| %>
<%= render partial: "test", locals: {form:form}, object: #application %>
<% end %>
I experienced this same issue when working on a Rails 6 application
I did an overriding of my routes due to some conflicts from
resources :sessions
to
resources :sessions, as: :sets
Here's how I fixed it:
app/views/sessions/new.html.erb
<h1>New Session</h1>
<%= form_with(model: #session, url: sets_path, local: true) do |form| %>
<%= render partial: 'form', session: #session, locals: { form: form } %>
<% end %>
<%= link_to 'Back', sets_path %>
Note: A URL was defined for the New Form since routing override was done. Thus, the form_with container was isolated from the _form.html.erb partial. This is in a bid to avoid creating multiple _form.html.erb partials for the new.html.erb and edit.html.erb files, since they have different URLs.
app/views/sessions/edit.html.erb
<%= form_with(model: #session, url: set_path(#session), local: true) do |form| %>
<%= render partial: 'form', session: #session, locals: { form: form } %>
<% end %>
<%= link_to 'Show', set_path(session) %> |
<%= link_to 'Back', sets_path %>
Note: A URL was defined for the New Form since routing override was done. Thus, the form_with container was isolated from the _form.html.erb partial. This is in a bid to avoid creating multiple _form.html.erb partials for the new.html.erb and edit.html.erb files, since they have different URLs.
app/views/sessions/_form.html.erb
<% if #session.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#session.errors.count, "error") %> prohibited this session from being saved:</h2>
<ul>
<% #session.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :prefix %>
<%= form.text_field :prefix %>
</div>
<div class="actions">
<%= form.submit %>
</div>
Note: Notice that there is no form helper definition in the _form.html.erb file, it was moved to the new.html.erb and edit.html.erb files, since they now have different URLs due to the modification of their route.
app/views/sessions/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Sessions</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th>Prefix</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #sessions.each do |session| %>
<tr>
<td><%= session.name %></td>
<td><%= session.prefix %></td>
<td><%= link_to 'Show', set_path(session) %></td>
<td><%= link_to 'Edit', edit_set_path(session) %></td>
<td><%= link_to 'Destroy', set_path(session), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Session', new_set_path %>
Note: Pay attention to the modification of the link URLs in the new action.
app/views/sessions/show.html.erb
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= #session.name %>
</p>
<p>
<strong>Prefix:</strong>
<%= #session.prefix %>
</p>
<%= link_to 'Edit', edit_session_path(#session) %> |
<%= link_to 'Back', sessions_path %>
Note: Pay attention to the modification of the link URLs in the edit and back actions.
app/controllers/sessions_controller.rb
class SessionsController < ApplicationController
before_action :set_session, only: [:show, :edit, :update, :destroy]
# GET /sessions
# GET /sessions.json
def index
#sessions = Session.all
end
# GET /sessions/1
# GET /sessions/1.json
def show
end
# GET /sessions/new
def new
#session = Session.new
end
# GET /sessions/1/edit
def edit
end
# POST /sessions
# POST /sessions.json
def create
#session = Session.new(session_params)
respond_to do |format|
if #session.save
format.html { redirect_to sets_path(#sesion), notice: 'Session was successfully created.' }
format.json { render :show, status: :created, location: sets_path(#sesion) }
else
format.html { render :new }
format.json { render json: #session.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /sessions/1
# PATCH/PUT /sessions/1.json
def update
respond_to do |format|
if #session.update(session_params)
format.html { redirect_to sets_path(#sesion), notice: 'Session was successfully updated.' }
format.json { render :show, status: :ok, location: sets_path(#sesion) }
else
format.html { render :edit }
format.json { render json: #session.errors, status: :unprocessable_entity }
end
end
end
# DELETE /sessions/1
# DELETE /sessions/1.json
def destroy
#session.destroy
respond_to do |format|
format.html { redirect_to sets_url, notice: 'Session was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_session
#session = Session.find(params[:id])
end
# Only allow a list of trusted parameters through.
def session_params
params.require(:session).permit(:name, :prefix)
end
end
Note: Pay attention to the modification of the redirect URLs in the create and update actions.
That's all.
I hope this helps

act_as_taggable Gem Ruby on Rails Error: NoMethodError in Posts#index

I am trying to add Tags to my Posts Scaffold using the act_as_taggable Gem but i get an error when i view the index or the show page. I have followed this guide but i still get the error.
here's my code:
posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
# GET /posts.json
def index
#posts = Post.all
#posts = Post.tagged_with(params[:tag])
#posts = Post.all.order("created_at DESC")
end
# GET /posts/1
# GET /posts/1.json
def show
end
# GET /posts/new
def new
#post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
# POST /posts.json
def create
#post = Post.new(post_params)
respond_to do |format|
if #post.save
format.html { redirect_to #post, notice: 'Post was successfully created.' }
format.json { render :show, status: :created, location: #post }
else
format.html { render :new }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /posts/1
# PATCH/PUT /posts/1.json
def update
respond_to do |format|
if #post.update(post_params)
format.html { redirect_to #post, notice: 'Post was successfully updated.' }
format.json { render :show, status: :ok, location: #post }
else
format.html { render :edit }
format.json { render json: #post.errors, status: :unprocessable_entity }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.json
def destroy
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
#post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:name, {image:[]}, :tag_list)
end
end
post.rb
class Post < ActiveRecord::Base
acts_as_taggable
mount_uploaders :image, ImageUploader
end
views/posts/_form.html.erb
<%= form_for(#post , html: { multipart: true }) do |f| %>
<% if #post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#post.errors.count, "error") %> prohibited this post from being saved:</h2>
<ul>
<% #post.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :image %><br>
<%= f.file_field :image , multiple: true %>
</div>
<div class="form-group">
<%= f.label :tag_list, "Tags (separated by commas)" %>
<%= f.text_field :tag_list, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
views/posts/index.html.erb
<p id="notice"><%= notice %></p>
<h1>Listing Posts</h1>
<table>
<thead>
<tr>
<th>Name</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= link_to 'Show', post %></td>
<td><%= link_to 'Edit', edit_post_path(post) %></td>
<td><%= link_to 'Destroy', post, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<%= #posts.tags.each do |tag| %>
<span class="label label-teal">
<%= link_to tag.name, tag_path(tag.name) %>
</span>
<% end %>
<br>
<%= link_to 'New Post', new_post_path %>
views/posts/show.html.erb
<p id="notice"><%= notice %></p>
<%= image_tag #post.image%>
<p>
<strong>Name:</strong>
<%= #post.name %>
</p>
<% #posts.tags.each do |tag| %>
<span class="label label-teal">
<%= link_to tag.name, tag_path(tag.name) %>
</span>
<% end %>
<%= link_to 'Edit', edit_post_path(#post) %> |
<%= link_to 'Back', posts_path %>
config/routes.rb
Rails.application.routes.draw do
resources :posts
get 'tags/:tag', to: 'pins#index', as: :tag
end
Did anyone had a solution to this issue ?
You're calling tags on a collection of Posts, but it's the individual posts that have tags.
Either select a single post and run tags on that, or use Tag.all or something similar to find all tags in the system.

Couldn't find Post without an ID / ActiveRecord::RecordNotFound

I know this is a very basic solution however, I am just not seeing it right now. I am getting a 'Couldn't find Post without an ID' error within CommentsController#create.
I created a 'New Comment' button under the post which should then redirect to the comment form. From there once a user inputs their comments and clicks the 'Create Comment' button the comment should be displayed under the original post. Thank you in advance.
Comments Controller
Class CommentsController < ApplicationController
before_filter :authenticate_user!
def new
#comment = Comment.new
end
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:commenter, :body))
respond_to do |format|
if #comment.save
format.html { redirect_to #post, notice: 'Comment was successfully created.' }
format.json { render json: #comment, status: :created, location: #comment }
else
format.html { render action: "new" }
format.json { render json: #comment.errors, status: :unprocessable_entity }
end
end
end
def destroy
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.destroy
redirect_to post_path(#post)
end
def show
#comment = Comment.new
end
end
Post/Show
<div class="row">
<div class="col-md-offset-4 col-med-8">
<div class="panel panel-default">
<div class="panel-heading center">
<% if #post.image.url %>
<%= image_tag #post.image.url(:medium) %>
<% elsif #post.video.url %>
<%= video_tag #post.video.url(:medium), controls: true, type: "video/mp4" %>
<% end %></br>
<p>
<strong>Likes:</strong>
<%= #post.get_likes.size%>
</p>
<%=link_to image_tag('like.jpg', :border => 0), likes_post_path(#post) %>
<%=link_to image_tag('unlike.jpg', :border => 0), dislikes_post_path(#post) %>
</div>
<div class="panel-body">
<p><%= #post.description %></p>
<% user = #post.user %>
<p><strong><%= link_to(user.name, user_path(user)) if #post.user %></strong></p>
<%= link_to 'New Comment', new_comment_path, class: "btn btn-danger btn-sm active" %></br>
<br><% if #post.user == current_user %>
<%= link_to edit_post_path(#post) do %>
<span class="glyphicon glyphicon-edit"></span>
Edit
<% end %>
<% end %>
<%= link_to 'Back', posts_path %>
</div>
</div>
</div>
Comments / _form
<%= form_for [#post, Comment.new] do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :body %><br>
<%= f.text_area :body %>
</div>
<div class="actions">
<%= f.submit class: "btn btn-danger btn-sm" %>
</div>
<% end %>
Routes
resources :comments
resources :posts do
resources :comments
end
Comments / Show
<p id="notice"><%= notice %></p>
<p>
<strong>Post:</strong>
<%= #comment.post_id %>
</p>
<p>
<strong>Body:</strong>
<%= #comment.body %>
</p>
<%= link_to 'Edit', edit_comment_path(#comment) %> |
<%= link_to 'Back', comments_path %>
Rake Routes
post_comments GET /posts/:post_id/comments(.:format) comments#index
POST /posts/:post_id/comments(.:format) comments#create
new_post_comment GET /posts/:post_id/comments/new(.:format) comments#new
edit_post_comment GET /posts/:post_id/comments/:id/edit(.:format) comments#edit
post_comment GET /posts/:post_id/comments/:id(.:format) comments#show
I recommend making the following changes:
Routes:
Remove the first resources :comments. Leave the following:
resources :posts do
resources :comments
end
Posts/Show view:
You should be using new_post_comment_path instead of new_comment_path. Run rake routes to see why.
CommentsController#new:
Define #post in your new action:
def new
#post = Post.find(params[:post_id])
#comment = Comment.new
end
Finally, in Comments/_form:
Change <%= form_for [#post, Comment.new] do |f| %> to <%= form_for [#post, #comment] do |f| %>. Although I believe <%= form_for #comment do |f| %> should work.
I recommend going through the Rails Guides for additional information and explanations.
I believe that in def new of the comments controller, you also need to set #post, not just #comment

flash[:notice] not working in Rails 4 after edit/create action

I can get flash messaging to work after create and destroy when they are redirected to root_path but cannot get it to work when update redirects to show.html.erb for some reason. What do you think is the problem? My Quote model has 4 columns(id, category, author and quotetext)
My show view
<% if !flash[:notice].blank? %>
<div class="notice">
<%= flash[:notice] %>
</div>
<% end %>
<% #category.each do |quote| %>
<div>
<p><strong> <%= quote.category %></strong></p>
<p><em><%= quote.author %></em></p>
<p> <%= quote.text %> </p>
<hr>
</div>
<% end %>
<%= link_to 'Home', quotes_path %>
My controller:
class QuotesController < ApplicationController
before_action :set_quote, only: [:show, :edit, :update, :destroy]
# GET /quotes
# GET /quotes.json
def index
#quotes = Quote.sorted
end
# GET /quotes/1
# GET /quotes/1.json
def show
#quote = Quote.find(params[:id])
end
# GET /quotes/new
def new
#quote = Quote.new
#apparently this doesn't really do anything but good to specify
end
def create
#quote = Quote.new(quote_params)
if #quote.save
flash[:notice] = "Quote #{#quote.pkey} created!"
redirect_to root_path
else
render('new')
end
end
# GET /quotes/1/edit
def edit
#quote = Quote.find(params[:id])
end
# PATCH/PUT /quotes/1
# PATCH/PUT /quotes/1.json
def update
#quote = Quote.find(params[:id])
if #quote.update_attributes(quote_params)
flash[:notice] = "Quote #{#quote.pkey} updated!"
redirect_to(:action => 'show', :id => #quote.id)
else
render('edit')
end
end
# DELETE /quotes/1
# DELETE /quotes/1.json
def destroy
#quote = Quote.find(params[:id]).destroy
flash[:notice] = "Quote #{#quote.pkey} deleted!"
redirect_to root_path
end
private
def set_quote
#quote = Quote.find(params[:id])
end
def quote_params
params.require(:quote).permit(:category, :author, :quotetext)
end
end
my index view
<div class='jumbotron'>
<h1>Root Index Page</h1>
</div>
<%= render 'shared/nav' %>
<div class="quotes index">
<%= render 'flash' %>
<table class="listing">
<tr class="header">
<th>Pkey</th>
<th>Category</th>
<th>Author</th>
<th>Quote Text </th>
</tr>
<% #quotes.each do |quote| %>
<tr>
<td><%=quote.pkey %></td>
<td><%=quote.category %></td>
<td><%=quote.author %></td>
<td><%=quote.text %></td>
<td class="actions">
<%= link_to("Show", {:action => 'show', :id => quote.id}) %>
<%= link_to("Edit", {:action => 'edit', :id => quote.id}) %>
<%= link_to quote_path(quote.id), method: :delete, data: {confirm: "Really delete Quote ##{quote.id}?"} do %><span class=edit>Delete</span><% end %>
</td>
</tr>
<% end %>
</table>
</div>
my edit view
<h1>Edit Existing Quote <%=#quote.pkey%> </h1>
<%= form_for(#quote) do |f| %>
<p>
<%= f.label :category %><br>
<%= f.text_field :category %>
</p>
<p>
<%= f.label :author %><br>
<%= f.text_field :author %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :quotetext %>
</p>
<div class="actions">
<%= f.submit "Update quote" %>
</div>
<% end %>
<%= link_to 'Show', #quote %> |
<%= link_to 'Back', quotes_path %>
flash partial
<% if !flash[:notice].blank? %>
<div class="notice">
<%= flash[:notice] %>
</div>
<% end %>
flash.keep is a method applied to flash an the params should be passed as argument, not array:
flash.keep(:notice)
http://guides.rubyonrails.org/action_controller_overview.html#the-flash
And the source code:
http://api.rubyonrails.org/classes/ActionDispatch/Flash/FlashHash.html#method-i-keep

Resources