1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

プルダウン(セレクトボックス)を使ってみよう -投稿先を選択する-

Posted at

大学生が集まるプログラミングコミュニティ
GeekSalon(https://bit.ly/2M64LXd) 名古屋メンタ-の吉田です。

セレクトボックスでカラムに入れるものを選択したい!
投稿先をindexだけじゃなく、複数のページにも出来るようにしたい!
とういう人のための記事です。また
投稿ボタンを押した後、セレクトした先にすぐ飛びたい!
というわがままな要望も[応用]として解決法を載せています。
是非参考にして下さい

##まずはセレクトボックスをつけてみよう
form_with, form_for でこんな感じのセレクトボックスをつけてみましょう
select
selectbox

こちらの記事を参考につけてみて下さい(丸投げ)
https://qiita.com/kawakami_shotaro/items/11a677bf34136cb7686d

##ゴール:複数のページに投稿出来るようにする
今回はユーザーが「和食・洋食・中華」の3つのジャンルから投稿先を選択するという機能を実装してみます。


##用意するもの

  • tweetsテーブルのgenreカラム(命名は自由です)
  • viewページ(今回はpage1,page2,page3を用意)

まずはこの2つを用意しましょう

コマンドプロンプトを開きtweetsテーブルにgenreカラムを追加していきましょう。自分のプロダクトの階層にcdして

コマンドプロンプト
rails g migration AddGenreToTweets genre:integer
rails db:migrate

カラムを追加=>データベースに変更を加える=>migrateでしたね。カラムの用意はこれで完了です(保存形式がintegerの理由は後ほど)

viewページはVScodeで3つパパッと作ってしまいましょう。名前はpage1,page2,page3と適当につけておきます(忘れた人は教材で確認!)

##本題:投稿先をindexだけじゃなく、複数のページにも出来るようにする
では実装するためのコードを書いていきましょう。投稿ページのプルダウンのコードはこんな感じです

new.html.erb
<%= stylesheet_link_tag 'new', :media => "all" %>

<div class="post-container">
    <p class="title">投稿フォーム</p>
    <%= form_for(@tweet, :url => { controller:'tweets', action:'create'})do |f| %>
    <%= f.label :投稿内容 %>
    <br>
    <%= f.text_field :body,size: 140%>
-----ここから変更-----
    <%= f.select :genre, [["和食", 1], ["洋食", 2], ["中華", 3]], include_blank: "選択して下さい" %>
-----ここまで------
    <div class="field">
      <%= f.label :画像選択 %>
      <%= f.file_field :image %>
    </div>
    <br>
    <%= f.submit "送信" %>
    <br>
    <% end %>
</div>

表示は和食ですが、実際カラムに入ってるのは1という風にしています(なので保存形式をintegerにしました)

次はコントローラーを変更しましょう

tweets_controller.rb
*省略*
    def page1
    @washokus = Tweet.where(genre: 1)
    end
    def page2
    @yoshokus = Tweet.where(genre: 2)
    end
    def page3
    @chukas = Tweet.where(genre: 3)
    end
*省略*
    private
    def tweet_params
        params.require(:tweet).permit(:body,:image,:genre)
    end

順に見ていきましょう

tweets_controller.rb
    def page1
    @washokus = Tweet.where(genre: 1)
    end

これは「genreカラムに1が入っているものだけを@washokusに代入」しています
この@washokusをpage1のviewで使うことで和食の投稿のみ表示されるように出来ます

tweets_controller.rb
    private
    def tweet_params
        params.require(:tweet).permit(:body,:image,:genre)
    end

genreカラムに入れたものを運べるよう、ストロングパラメーターにgenreを追加しましょう。これ結構忘れがちです

続いてルーティングを設定しましょう

routes.rb
  get 'tweets/page1' => 'tweets#page1'
  get 'tweets/page2' => 'tweets#page2'
  get 'tweets/page3' => 'tweets#page3'

余談ですが、ルーティングを書く際はidを扱うコードより上にこれらのコードを書くようにしましょう
(例:get 'tweets/:id' => 'tweets#show', as: 'tweet')
これはidにurlが入ってエラーになるのを防ぐためです

最後にviewページを作ってあげましょう

page1.html.erb
<%= stylesheet_link_tag 'index', :media => "all" %>
<h1>和食</h1>
<div class="tweets-container">
<% @washokus.each do |t| %>
    <div class="tweet">
      <%= link_to t.user.name, user_path(t.user.id) %>
      (♡<%= t.liked_users.count %>)
      <% if t.image.present? %>
        <%= image_tag t.image_url, :size => "500x300" %>
      <% end %>
      <div class="main-box">
        <div class="left-container"><%= t.body %></div>
        <div class=right-container>
          <%= link_to "詳細", tweet_path(t.id) %>
          <% if current_user.id == t.user.id %>
            <%= link_to "編集", edit_tweet_path(t.id) %>
            <%= link_to "削除", tweet_path(t.id), method: :delete %>
          <% end %>
        </div>
      </div>
      <p class="time"><%= t.created_at %></p>
    </div>
  <% end %>
</div>
page2.html.erb
<%= stylesheet_link_tag 'index', :media => "all" %>
<h1>洋食</h1>
<div class="tweets-container">
<% @yoshokus.each do |t| %>
    <div class="tweet">
      <%= link_to t.user.name, user_path(t.user.id) %>
      (♡<%= t.liked_users.count %>)
      <% if t.image.present? %>
        <%= image_tag t.image_url, :size => "500x300" %>
      <% end %>
      <div class="main-box">
        <div class="left-container"><%= t.body %></div>
        <div class=right-container>
          <%= link_to "詳細", tweet_path(t.id) %>
          <% if current_user.id == t.user.id %>
            <%= link_to "編集", edit_tweet_path(t.id) %>
            <%= link_to "削除", tweet_path(t.id), method: :delete %>
          <% end %>
        </div>
      </div>
      <p class="time"><%= t.created_at %></p>
    </div>
  <% end %>
</div>
page3.html.erb
<%= stylesheet_link_tag 'index', :media => "all" %>
<h1>中華</h1>
<div class="tweets-container">
<% @chukas.each do |t| %>
    <div class="tweet">
      <%= link_to t.user.name, user_path(t.user.id) %>
      (♡<%= t.liked_users.count %>)
      <% if t.image.present? %>
        <%= image_tag t.image_url, :size => "500x300" %>
      <% end %>
      <div class="main-box">
        <div class="left-container"><%= t.body %></div>
        <div class=right-container>
          <%= link_to "詳細", tweet_path(t.id) %>
          <% if current_user.id == t.user.id %>
            <%= link_to "編集", edit_tweet_path(t.id) %>
            <%= link_to "削除", tweet_path(t.id), method: :delete %>
          <% end %>
        </div>
      </div>
      <p class="time"><%= t.created_at %></p>
    </div>
  <% end %>
</div>

あとはこれらのページに飛べるよう、適当にリンクをindexに貼っておきましょう

index.html.erb
<%= link_to '和食', :controller => "tweets", :action => "page1" %>
<%= link_to '洋食', :controller => "tweets", :action => "page2" %>
<%= link_to '中華', :controller => "tweets", :action => "page3" %>

これで完成です!お疲れ様でした!

##[応用]投稿ボタンを押した後、セレクト先にすぐ飛ぶ機能
今のtweetsコントローラーはcreateアクションで

tweets_controller.rb
   if @tweet.save
      redirect_to :action => "index"

となっているので、投稿後はindexに飛ぶようになっています。これを変更します

tweets_controller.rb
    def create
        @tweet = Tweet.new(tweet_params)
        @tweet.user_id = current_user.id
        if @tweet.save and @tweet.genre == 1
            redirect_to :action => "page1"
        elsif @tweet.save and @tweet.genre == 2
            redirect_to :action => "page2"
        elsif @tweet.save and @tweet.genre == 3
            redirect_to :action => "page3"
        else
            redirect_to :action => "index"
        end
    end

A and Bは「AかつB」という条件を指します。つまりこの場合「"@tweetが保存される"かつ"genreカラムが1と合致する"」という条件を満たした場合、page1アクションが実行され、その結果page1にそのまま飛ぶようになっています。

セレクトボックスで何も選択しなかったり、保存に失敗した場合はindexに飛ぶようになってますね。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?