A memorandum about the ability to comment on posts
environment Ruby 2.6 series Rails 5.2 series
Library devise Slim
__ Rails app template for the above environment __ Procedure to set up Rails application and install devise and Slim
__ ↓ Image after implementation of comment function ↓ __
-User and Post are one-to-many relationships where User has many Posts. -User has many comments, and Post also has many comments. Many-to-many relationship. -Create an intermediate table and add a comment_content column to store the comment owner (user_id), the post that owns the comment (post_id), and the content of the comment for each record.
$ rails g devise User
$ rails g model Post post_content:string user:references
$ rails g model Comment comment_content:string user:references post:references
-Since devise is installed, the User model is created with the devise command.
-If you specify references, a foreign key (required) will be automatically set in the migration file.
users table
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
def change
create_table :users do |t|
## Database authenticatable
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
.
.
#
> User model
>```ruby:app/models/user.rb
class User < ApplicationRecord
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, dependent: :destroy
has_many :comments #User.You can get user-owned comments with comments.
end
posts table
class CreatePosts < ActiveRecord::Migration[5.2] def change create_table :posts do |t| t.text :post_content t.references :user, foreign_key: true t.timestamps end end end
> Post model
>```ruby:app/models/post.rb
class Post < ApplicationRecord
belongs_to :user
has_many :comments, dependent: :destroy #Post.You can get the comments w owned by the post with comments.
end
comments table
class CreateComments < ActiveRecord::Migration[5.2] def change create_table :comments do |t| t.text :comment_content t.references :user, foreign_key: true t.references :post, foreign_key: true t.timestamps end end end
> Comment model
>```ruby:app/models/comment.rb
class Comment < ApplicationRecord
belongs_to :user #Comment.Get the owner of the comment with user
belongs_to :post #Comment.Get the post with that comment on post
end
$ rails g controller posts index show
$ rails g controller comments
app/controllers/posts_controller.rb
class PostsController < ApplicationController
#Check the login status of the user. The index can be viewed without logging in.
before_action :authenticate_user!, only: [:show, :create]
def index
@posts = current_user.posts.all #Get all to display post list
@post = current_user.posts.new #Since a new post is made on the post list screen, get the Post object for the form parameter.
end
def show
@post = Post.find(params[:id])
@comments = @post.comments #Get all comments associated with post details
@comment = current_user.comments.new #Since the comment is posted on the post details screen, get the Comment object for the form parameter.
end
def create
@post = current_user.posts.new(post_params)
if @post.save
redirect_back(fallback_location: root_path) #After sending the comment, redirect to the previous page.
else
redirect_back(fallback_location: root_path) #Same as above
end
end
private
def post_params
params.require(:post).permit(:post_content)
end
end
-The id of the logged-in user is stored in all Posts and Comments acquired as current_user. It can be used because the association made in the model file and devise were introduced.
app/controllers/comments_controller.rb
class CommentsController < ApplicationController
def create
@comment = current_user.comments.new(comment_params)
if @comment.save
redirect_back(fallback_location: root_path) #After sending the comment, redirect to the previous page.
else
redirect_back(fallback_location: root_path) #Same as above
end
end
private
def comment_params
params.require(:comment).permit(:comment_content, :post_id) #post in form_Send id parameter and post to comment_It is necessary to store the id.
end
end
ruby:app/views/posts/index.html.slim
h2 post
= form_with model: @post do |f|
= f.text_area :post_content, placeholder: 'Text'
= f.submit
h2 post list
- @posts.each do |post|
= link_to post.post_content, post
= link_to 'home', root_path
ruby:app/views/posts/show.html.slim
h2 post details
= @post.post_content
h2 make a comment
= form_with(model:[@post, @comment], method: :post) do |f|
= f.text_area :comment_content
= f.hidden_field :post_id, value: @post.id
= f.submit 'To comment'
h2 comment list
- @comments.each do |comment|
= comment.comment_content #The content of the comment is displayed
= link_to 'home', root_path
· ``` Model: [@post, @comment]` `` Description for accessing nested routing. If you don't give two arguments properly, it will not be sent properly.
-In the hidden input field, the value post.id is sent with the parameter post_id. To store in the post_id of the Comment table.
config/routes.rb
Rails.application.routes.draw do
devise_for :users #Routing for user authentication created by devise
root to: 'posts#index' #Home screen is set to post list screen
resources :posts do #routing to posts controller
resources :comments, only: [:create] #comments Routing to controller
end
end
-By nesting comments resources within posts resources, it is convenient to specify a path such as post_comments_path.
This completes the implementation of the comment function.
[Let's make a comment function with Rails](https://qiita.com/nojinoji/items/2034764897c6e91ef982#%E3%83%AB%E3%83%BC%E3%83%86%E3%82%A3% E3% 83% B3% E3% 82% B0% E3% 81% AE% E4% BD% 9C% E6% 88% 90-1)
Recommended Posts