はじめに
今月の頭に小さなアプリを作ってみようと思い立ち、その中でランダムな画面遷移機能の実装に挑戦しました。
この時に作成したアプリはこちら
(2024年7月末まで稼働予定)
環境
ruby 3.2.2
rails 7.1.3.2
Render
MacBook
付けたい機能
「指定のリンクをクリックすると、その時々で異なる結果のページを表示させる」
これを実装するために今回は2種類の方法を取ってみました。
方法1
データベースに保存された値をランダムに表示させる方法
ランダムに表示したいデータベース作成
rails g model randam_rogers
(※randamの綴りが間違えていますがご了承ください)
class CreateRandamRogers < ActiveRecord::Migration[7.1]
def change
create_table :randam_rogers do |t|
t.string :body
t.string :short_body
t.timestamps
end
end
end
rails db_migrate
データの入力(ローカル環境での実装)
ターミナルで rails console
bodyカラムに入力したいワードを入れます
RandamRoger.create(body: "富、名声、力、この世の全てを手に入れた男”海賊王”ゴールド・ロジャー彼の死に際に放った一言は人々を海へ駆り立てた「俺の財宝か?欲しけりゃくれてやる、探せ!この世の全てをそこに置いてきた」男たちはグランドラインを目指し、夢を追い続ける。世はまさに、大海賊時代!")
今回はXでシェアしたいので、Xで投稿出来る長さの文章をshort_bodyカラムに入れます
RandamRoger.create(short_body: "「俺の財宝か?欲しけりゃくれてやる、探せ!この世の全てをそこに置いてきた」")
最終的に各カラムには3種類入れました。
結果を出力するためにページを用意
rails g controller pages
config/routes.rb
get "random_result", to: "pages#random_result"
pages_controller
def random_result
@randam_roger = RandamRoger.order('RANDOM()').first
end
出力するビューを作成
pages/random_result.html.erb
<% content_for(:title, 'ロジャーの言葉') %>
<h2>結果</h2>
<% if @randam_roger.present? %>
<%= @randam_roger.body %>
<div class="form-group">
<div class="btn-b">
<%= link_to "Xで共有する", "https://twitter.com/share?url=#{request.url}&text=#{URI.encode_www_form_component("#{@randam_roger.shortbody}")}&hashtags=#{URI.encode_www_form_component("ミニアプリ, トミメイセイ")}", target: '_blank' %>
</div>
<% else %>
※もう少しお待ちください
<% end %>
画面遷移前のビューを用意
<div class="btn-b">
<%= link_to "ガチャを引く", random_result_path %>
</div>
結果
3パターン作ったので、更新ボタンを押すとランダムで文章が出力されます。
完了、しかし…
こちらはローカルではうまくいったのですが、ターミナルから本番環境でデータを作成することがなぜかうまく行かず調べるも解決が出来ませんでした。そのためこの方法は断念しました。
ではデータベースを使わない方法で画面遷移をする方法がないかと考え、次の方法を取りました。
方法2
遷移先の数だけページを用意する方法
こちらはjavascriptを使用します。
ページを用意
rails g controller pages
結果の数だけページを用意します
touch app/views/pages/result1
アプリでは5パターン用意することに決めたのでresult5まで用意しました。
config/routes.rb
get "result1", to: "pages#result1"
get "result2", to: "pages#result2"
get "result3", to: "pages#result3"
get "result4", to: "pages#result4"
get "result5", to: "pages#result5"
pages_controller
def result1; end
def result2; end
def result3; end
def result4; end
def result5; end
ページを書く
pages/result1.html.erb
<% content_for(:title, 'ガチャ結果1') %>
<h2>結果(1/5)</h2>
<div style="text-align: center;">
<div class="form-group">
<strong>
1人きりで学習を進める事を放棄したモンキー ・D・ルフィ
</strong>
</div>
<%= image_tag 'mugiwarabouhi.png' %>
<div class="form-group">
<strong>「おれは助けてもらわねェと生きていけねェ自信がある!!!」</strong>
</div>
</div>
<div class="form-group">
<div class="btn-b">
<%= link_to "Xで共有する", "https://twitter.com/share?url=#{request.url}&text=#{URI.encode_www_form_component("1人きりで学習を進める事を放棄したモンキー ・D・ルフィ「おれは助けてもらわねェと生きていけねェ自信がある!!!」")}&hashtags=#{URI.encode_www_form_component("ミニアプリweek,トミメイセイ")}", target: '_blank' %>
</div>
<div class="btn">
<%= link_to "タイトルへ", root_path %>
</div>
残りのページもそれぞれ書きます。
(※方法1から2に変える際に、表示させるビューの中身を変えることにしました。)
画面遷移させたいページにリンクとjavascriptコードを書く
本来はjavascriptを読み込ませた方が良いと思うのですが、今回は直接書いてしまいました。
<div class="btn-b">
<a href="#" id="button">ガチャを引く</a>
</div>
<!-- 中略 -->
<script>
document.getElementById("button").addEventListener('click', function() {
const subjectArray = [
'https://tomi-meisei.onrender.com/result1', 'https://tomi-meisei.onrender.com/result2', 'https://tomi-meisei.onrender.com/result3',
'https://tomi-meisei.onrender.com/result4', 'https://tomi-meisei.onrender.com/result5'
];
const subject = subjectArray[Math.floor(Math.random() * subjectArray.length)];
window.location.href = subject;
});
</script>
"button"をクリックする事でjavascriptが動くよう設定します。
また画面遷移先のURLは本番環境で表示されるURLを書きます。
結果
実際の挙動は下記のURLを参照ください。
おまけ
今回の記事では、紹介した自作アプリにおける「某人気漫画キャラガチャ」における機能を説明しました。
このアプリでは他にも「某人気漫画プロローグメーカー」(メールアドレスでのユーザー登録必須)も搭載しておりますので、お時間あれば遊んでいただけると嬉しいです。