[Ruby on Rails] Posting function that only logged-in users can post

Target

post.gif

Development environment

ruby 2.5.7 Rails 5.2.4.3 OS: macOS Catalina

Premise

Build name login environment with devise The controller name is post (only the post function this time)

1. Creating a table

Added Post model

Terminal


$ rails g model Post user:references title:string body:string

When executed, it will be as follows, a column will be added and it can be saved.

db/migrate/xxxxxxxxxxxxx_create_posts.rb


class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.references :user, foreign_key: true
      t.string :title
      t.string :body

      t.timestamps
    end
  end
end

Supplement t.references: user, foreign_key: true is the user's foreign key. For foreign keys, click here (https://qiita.com/kamillle/items/5ca2db470f199c1bc3ef).

Terminal


$ rails db:migrate

Edit model

app/models/post.rb


class Post < ApplicationRecord
  belongs_to :user
end

app/models/user.rb


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 ← Add here
end
Explanation Depending on user: references when creating the controller On the post side, belongs_to: user is described, and 1 post 1 post can save who's post. By adding has_many: posts, dependent:: destroy on the user side You can create a one-to-many relationship, and one user can post many posts.

2. Creation of controller

Terminal


$ rails g controller posts create new

app/controllers/posts_controller.rb


class PostsController < ApplicationController
  before_action :authenticate_user!
  def create
  	@post = Post.new(post_params)  #Specify what to save newly
  	@post.user_id = current_user.id  #Specify who posted
  	if @post.save  #If you can save
   	 redirect_to new_post_path  #Transition to the posting screen
  	else  #If you can't
   	 render :new  #Transition to new
  	end
  end

  def new
   @post = Post.new
   @posts = Post.all
  end

  private  #Strong parameter (a function to prevent vulnerabilities that change unexpected values)
  def post_params
   params.require(:post).permit(:title, :body)  #Allow title and body changes
  end
end

Supplement By writing before_action: authenticate_user! Even if you type the URL, you cannot execute the new / create action unless you are logged in. Make a transition to the login screen.

Changed as below.

config/routes.rb


  get 'posts/create'← Delete
  get 'posts/new'← Delete
  resources :posts, only: [:create, :new]← Add

↓ After change

config/routes.rb


Rails.application.routes.draw do
  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
  }
  root 'homes#top'
  get 'mypage', to: 'homes#mypage'
  resources :posts, only: [:create, :new]← Add
end
Supplement resources is a RESTful URL, and descriptions such as get and patch can be omitted.

3. Changes to Views

Right-click and delete app / views / posts / create.html.erb.

erb:app/views/posts/new.html.erb


<h1>Posts#new</h1>
<span>Currently logged in user:<%= current_user.name %></span>![Screen recording 2020-09-01 22.17.23.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/512682b6-24c4-0a5b-fc87-35fc7806c02f.gif)

<%= form_for(@post, url: posts_path) do |f| %>
	<div>
		<%= f.label :title%><br>
		<%= f.text_field :title, autofocus: true %>
	</div>
	<div>
		<%= f.label :contents%><br>
		<%= f.text_area :body %>
	</div>
	<div><%= f.submit "Post" %></div>
<% end %>


<table>
	<thead>
		<tr>
			<th>Posted by name</th>
			<th>title</th>
			<th>Text</th>
		</tr>
	</thead>
	<tbody>
		<% @posts.each do |post| %>
			<tr>
				<td><%= post.user.name %></td>
				<td><%= post.title %></td>
				<td><%= post.body %></td>
			</tr>
		<% end %>
	</tbody>
</table>
Supplement Post function with form_for helper, post content acquisition with each method.

Recommended Posts