2020年5月5日火曜日

簡易SNSを作ってみよう(9)

投稿ボタンの作成
投稿を扱うコントローラとビューを作成する.

【手順】
bin/rails g controller posts create
vi config/routes.rb
(以下のように修正する)
Rails.application.routes.draw do
  #get 'posts/create'
  #get 'users/show'
  devise_for :users, controllers: {
        sessions:      'users/sessions',
        passwords:     'users/passwords',
        registrations: 'users/registrations'
  }
  root to: 'home#index'
  resources :users, :only => [:show]
  resources :posts, :only => [:create]
end

vi app/views/users/show.html.erb
(以下を追記.対象ユーザーのidをhidden_fieldで渡している点に注意)
<h1>MyPage for <%= @user.fullname %></h1>
  
<% if @students != nil %>
  <ul>
   <% @students.each {|st| %>
    <li><%= link_to st.fullname, user_path(st.id) %></li>
   <% } %>
  </ul>
<% end %>

<%= form_with model: Post.new do |f| %>
  <%= f.text_area :body, placeholder: "Add your comment" %><br />
  <%= f.hidden_field :id, { value: @user.id } %>
  <%= f.submit 'submit' %>
<% end %>

<% if @posts != nil %>
   <% l = @posts.length; @posts.each_with_index {|post, i| %>
    <p><%= (l-i).to_s + " : " + post.created_at.to_s %><br /> 
    <%= post.body %></p>
   <% } %>
<% end %>
投稿処理コントローラの作成
投稿を処理するコントローラを作成する.

【手順】
vi app/controllers/posts_controller.rb
(以下を追記)
class PostsController < ApplicationController
  def create
    p = post_params
    user = User.find(p[:id])
    if user.posts.create(body: p[:body])
      flash[:notice] = 'Post was successfully created.'
    else
      flash[:alert] = 'Something went wrong'
    end

    redirect_to user_path(user.id)
  end

  protected
  def post_params
    params.require(:post).permit(:body, :id)
  end
end
投稿のテスト
サーバを起動し,投稿がうまく行われることを確認する.なお,このままだと,マイページを開いているユーザーの投稿を,他人が書き加えてしまうことができる点で問題である.したがって,次は,コメント投稿者のカラムを追加する処理を行う.
投稿者IDの追加
コメント投稿者(submitter)の情報をPostに追加して,誰のコメントか分かるようにする.
まずは,投稿者のIDを追加する.

【手順】
bin/rails g migration add_submitter_to_posts submitter:integer
bin/rails db:migrate
投稿処理の修正
投稿を扱うコントローラを修正する.

【手順】
vi app/controllers/posts_controller.rb
(以下を修正する)
class PostsController < ApplicationController
  def create
    p = post_params
    user = User.find(p[:id])
    if user.posts.create(body: p[:body], submitter: current_user.id)
      flash[:notice] = 'Post was successfully created.'

vi app/views/users/show.html.erb
(以下を修正する)
<h1>MyPage for <%= @user.fullname %></h1>

…(略)…
<% if @posts != nil %>
  <% l = @posts.length; @posts.each_with_index {|post, i|
     sid = post.submitter
     sname = (sid != nil) ? User.find(sid).fullname : 'Anonymous ' %>
  <p>
    <%= (l-i).to_s + ' : ' + sname + ', ' post.created_at.to_s %><br />        
    <%= post.body %></p>
  <% } %>
<% end %>
投稿のテスト
どのユーザーでもよいのでログインして投稿のテストを行う.正しく動作することを確認する.

無意味な投稿防止のための修正

空欄のコメントは受け付けないように,投稿を扱うコントローラを修正する.

【手順】
vi app/controllers/posts_controller.rb
(以下を修正する)
class PostsController < ApplicationController
  def create
    p = post_params
    user = User.find(p[:id])
    if (p[:body] == '')
      flash[:alert] = 'Null comment is not permitted.'
    else
     if user.posts.create(body: p[:body], 
submitter: current_user.id)
        flash[:notice] = 'Post was successfully created.'
      else
        flash[:alert] = 'Something went wrong'
      end
    end
…(略)… 

ついでに,改行を<br />に変換して適切に表示されるよう,ビューを修正する.
本文をクォートして分かりやすく表示させる変更も加え,また,投稿者の名前部分はハイパーリンクとして投稿者のマイページにリンクさせるようにする.

【手順】
vi app/views/users/show.html.erb
(以下を修正する)
…(略)… 
<% if @posts != nil %>
  <% l = @posts.length; @posts.each_with_index {|post, i|
      sid = post.submitter
      sname = (sid != nil) ? User.find(sid).fullname
                           : 'Anonymous ' %>
    <p><%= (l-i).to_s + ' : ' %>
       <%= (sid != nil) ? (link_to sname, user_path(sid)) : sname %>
       <%= post.created_at.to_s %>
    <blockquote><%= simple_format(h(post.body)) %>
    </blockquote></p>
   <% } %>
<% end %>

0 件のコメント:

コメントを投稿