Я реализую комментарии для постов, и они должны быть показаны в индексе постов, но комментарий не будет создан.
Я пробовал много способов получить решение, но безрезультатно, этопоследний.
Модель пользователя
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and
:omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, dependent: :destroy
has_many :likes, dependent: :destroy
has_many :comments, dependent: :destroy
before_save :downcase_email
validates :name, presence: true, length: { maximum: 50 },
allow_blank: false
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.
[a-z]+\z/i.freeze
validates :email, presence: true, length: { maximum: 255 },
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
validates :password, presence: true, length: { minimum: 6 },
allow_nil: false, allow_blank: false
private
# Converts email to all lower-case.
def downcase_email
self.email = email.downcase
end
end
Почтовая модель
class Post < ApplicationRecord
belongs_to :user
has_many :likes, dependent: :destroy
has_many :comments, dependent: :destroy
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
validates :user_id, presence: true
validates :content, presence: true, length: { maximum: 300 }
validate :picture_size
private
# Validates the size of an uploaded picture.
def picture_size
errors.add(:picture, 'image size could not be more than
5MB') if picture.size > 5.megabytes
end
end
Комментарий модели
class Comment < ApplicationRecord
belongs_to :user
belongs_to :post
validates :user_id, presence: true
validates :body, presence: true, length: { maximum: 300 }
validates :post_id, presence: true
default_scope -> { order(created_at: :desc) }
end
Контроллер приложений
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
# to avoid error message "undefined method `errors' for
nil:NilClass"
before_action :instantiate_post
before_action :instantiate_comment
def instantiate_post
@post = Post.new
end
def instantiate_comment
@comment = Comment.new
end
end
Контроллер пользователей
class UsersController < ApplicationController
#before_action :set_user, only: %i[show edit update destroy]
before_action :authenticate_user!, only: %i[create destroy]
before_action :current_user, only: %i[create destroy]
def index
@users = User.all
end
def show
@user = User.find_by(id: params[:id])
@posts = @user.posts
@comments = @post.comments
@comment = current_user.comments.build(:post => @post)
end
def profile
@user = User.find_by(id: params[:id])
end
def destroy
@user = User.find_by(id: params[:id])
@user.destroy
respond_to do |format|
format.html { redirect_to users_path, notice: 'User was
successfully destroyed.' }
format.json { head :no_content }
end
end
private
# def set_user
# # @user = User.find(params[:id])
# end
# Never trust parameters from the scary internet, only
allow the white list through.
def user_params
params.require(:user).permit(:name, :email, :password)
end
end
Контроллер сообщений
class PostsController < ApplicationController
before_action :set_post, only: %i[show edit update destroy]
before_action :authenticate_user!, only: %i[create destroy]
before_action :current_user, only: %i[create destroy]
def index
@posts = Post.all
end
def show; end
def new
@post = Post.new
end
def edit; end
def create
@post = current_user.posts.build(post_params)
respond_to do |format|
if @post.save
format.html { redirect_to authenticated_root_path,
notice: 'Post was successfully created.' }
format.json { render :show, status: :created,
location: @post }
else
format.html { redirect_to current_user, alert: 'post
not created' }
format.json { render json: @post.errors, status:
:unprocessable_entity }
end
end
end
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
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(:content, :picture)
end
end
Контроллер комментариев
class CommentsController < ApplicationController
before_action :set_post, only: %i[update destroy]
before_action :set_comment, only: %i[update destroy]
before_action :authenticate_user!, only: %i[create destroy]
before_action :current_user, only: %i[create destroy]
def index
@comments = Comment.all
end
def new
@comment = Comment.new
end
def update
respond_to do |format|
if @comment.update(comment_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
def destroy
@comment.destroy
respond_to do |format|
format.html { redirect_to posts_url, notice: 'Post was
successfully destroyed.' }
format.json { head :no_content }
end
end
def create
@comment = @post.comments.build(comment_params)
@comment.user = current_user
respond_to do |format|
if @comment.save
format.html { redirect_to @post, notice: 'Post was
successfully commented.' }
format.json { render :show, status: :created,
location: @post }
else
format.html { redirect_to @post, alert: 'post not
commented' }
format.json { render json: @post.errors, status:
:unprocessable_entity }
end
end
end
private
def comment_params
params.require(:comment).permit(:body, :post_id)
end
def set_post
@post = Post.find(params[:post_id])
end
def set_comment
@comment = @post.comments.find(params[:id])
end
end
просмотров / сообщений / индекса
<div class="row">
<p id="notice"><%= notice %></p>
<div class="col-md-6 form-new-user col-md-offset-3">
<h1>Posts</h1>
<%=render "form",post: @post =%> <br>
<% @posts.each do |post| %>
<ol class='posts'>
<%= render post =%>
<p>Comment on This Post</p>
<%= render "comments/form" ,post: post=%>
<%= render @post.comments %>
</ol>
<% end %>
</div>
</div>
просмотров / комментариев/_comment.html.erb
<li id="comment-<%= comment.id %>">
<%= link_to gravatar_for(comment.user, size: 30), comment.user
%>
<span class="user"><%= link_to comment.user.name, comment.user
%></span>
<span class="content">
<%= comment.body %>
<%= image_tag post.picture.url if post.picture? %>
</span>
<span class="timestamp">
At: <%= (comment.created_at) %>
<% if current_user == post.user || current_user ==
comment.user %>
<%= link_to 'Edit', edit_post_path(post) %> |
<%= link_to "delete", post, method: :delete,
data: { confirm: "You
sure?" } %>
<% end %>
</span>
</li>
views / comments / _form.html.erb
<%= form_for [post, Comment.new] do |f| %>
<%= f.hidden_field :post_id, value: post.id %>
<%= f.label :body %><br>
<%= f.text_area :body ,class:"form-control"%><br>
<%= f.submit "Replay", class: "btn btn-primary" %>
<% end %>
Routes.rb
Rails.application.routes.draw do
resources :posts do
resources :comments
end
# For details on the DSL available within this file, see
http://guides.rubyonrails.org/routing.html
devise_for :users, controllers: { registrations:
'users/registrations' }
as :user do
authenticated :user do
root 'posts#index', as: :authenticated_root
end
unauthenticated do
root 'devise/registrations#new', as: :unauthenticated_root
end
end
resources :users, only: %i[index show destroy]
get '/users/:id/profile', to: 'users#profile', as: 'profile'
end
Получение отката
Started POST "/posts/250/comments" for ::1 at 2019-10-01
12:46:45 +0100
Processing by CommentsController#create as HTML
Parameters: {"utf8"=>"✓",
"authenticity_token"=>"KNntIHqHzAQ9RWylAUoXa+NmEvMTL
ZaewL2Z3wrO0ZB921j1YGjYJA6OAXVjDCQ1GNuN0Okv4tuSp4BacDXwqA=="
,"comment"=>{"post_id"=>"250", "body"=>"fixed?"},
"commit"=>"Replay", "post_id"=>"250"}
User Load (0.7ms) SELECT "users".* FROM "users" WHERE
"users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2
[["id", 1], ["LIMIT", 1]]
↳/home/othmane/.rbenv/versions/2.6.1/lib/ruby/gems/
2.6.0/gems/activerecord-
5.2.3/lib/active_record/log_subscriber.rb:98
(0.2ms) BEGIN
↳ app/controllers/comments_controller.rb:40
(2.7ms) ROLLBACK
↳ app/controllers/comments_controller.rb:40
Redirected to http://localhost:3000/posts
Completed 302 Found in 22ms (ActiveRecord: 3.6ms)