やりたいこと
リロードしてもチェックボックスの値を維持する
実装したらこんな感じ
仕組み(ゴリ押し)
- javascriptで全てのcheckboxのtrue/falseをリストに格納
- そのリストを「次へ」ボタンが押されたときにコントローラに送り、保存する
- 「次へ」ボタンを押したらリロードするので、その時にデータベースから最新のcheckbox情報が入ったレコードをviewに渡す
- 受け取ったリストに基づいてjavascriptを用いてチェックをつけていく
実装
checkboxがtrueかfalse保存する用のモデル作成!
1行ずつ実行してください
ターミナル
rails g model Check list:string
rails db:migraate
コントローラ変えていきます
tweets_controller.rb
# 省略
def gatya
# 省略
check = Check.new #新しいCheck
check.list = params[:check] #checksテーブルのlistカラムにviewから受け取ったparamsを代入
check.save #データベースに保存
@checks = Check.order(created_at: :desc).limit(1) #checksテーブルから最新のレコードを取得
end
# 省略
リロード前後で値を保持したいcheckboxにclass名を付けます
gatya.html.erb
<%= form_tag({controller:"tweets",action:"gatya"}, method: :get) do %>
<div class="game">
<% if !@tweet.nil? %>
<h1><%= @tweet.name %></h1>
<% else %>
<h1>no hit</h1>
<% end %>
<button type="submit" id="submit">
<i class="fa-solid fa-arrows-rotate"></i>
次へ
</button>
</div>
ジャンル:
<% Genre.all.each do |g| %>
<%= check_box :genre_ids, g.name, checked:true, class:"check" %><%= g.name %> # class:"check"を追加
<% end %><br>
機種:
<% Console.all.each do |t| %>
<%= check_box :console_ids, t.name, checked:true, class:"check" %><%= t.name %> # class:"check"を追加
<% end %><br>
<input type="hidden" name="check" id="check"> #ここにcheckboxのtrue/falseの配列が代入され、コントローラに渡される
<% end %>
<% @checks.each do |c| %>
<input type="hidden" id="list" value=<%= c.list %>>
<% end %>
また、同じページにjavascriptを書いていきます
gatya.html.erb
<%= form_tag({controller:"tweets",action:"gatya"}, method: :get) do %>
# 省略
<% end %>
<script>
var box = document.querySelectorAll('.check');
function check(){
let check_list = [];
for (let i = 0;i < box.length;i++){
check_list.push(box[i].checked);
}
document.querySelector('#check').value = check_list;
}
document.querySelector('#submit').addEventListener("click", check);
var count = 0;
for (let j = 0;j < box.length;j++){
box[j].addEventListener("click", check);
let check_list = document.querySelector('#list').value.split(',');
if (check_list[j] == "true"){
box[j].checked = true;
}else {
box[j].checked = false;
count += 1;
}
}
if (count == box.length){
for (let k = 0;k < box.length;k++){
box[k].checked = true;
}
}
</script>
終わりいいいいいい!!!!!!!!!!
ここまで読んでいただいてありがとうございます!!他の記事より圧倒的にわかりにくかったと思うので、全体像載せときます↓↓
gatya.html.erb
<div class="all-container">
<h1>次やるゲームはこれだああ!!!!</h1>
<%= form_tag({controller:"tweets",action:"gatya"}, method: :get) do %>
<div class="game">
<% if !@tweet.nil? %>
<h1><%= @tweet.name %></h1>
<% else %>
<h1>no hit</h1>
<% end %>
<button type="submit" id="submit">
<i class="fa-solid fa-arrows-rotate"></i>
次へ
</button>
</div>
ジャンル:
<% Genre.all.each do |g| %>
<%= check_box :genre_ids, g.name, checked:true, class:"check" %><%= g.name %>
<% end %><br>
機種:
<% Console.all.each do |t| %>
<%= check_box :console_ids, t.name, checked:true, class:"check" %><%= t.name %>
<% end %><br>
<input type="hidden" name="check" id="check">
<% end %>
<% @checks.each do |c| %>
<input type="hidden" id="list" value=<%= c.list %>>
<% end %>
</div>
<script>
var box = document.querySelectorAll('.check');
function check(){
let check_list = [];
for (let i = 0;i < box.length;i++){
check_list.push(box[i].checked);
}
document.querySelector('#check').value = check_list;
}
document.querySelector('#submit').addEventListener("click", check);
var count = 0;
for (let j = 0;j < box.length;j++){
box[j].addEventListener("click", check);
let check_list = document.querySelector('#list').value.split(',');
if (check_list[j] == "true"){
box[j].checked = true;
}else {
box[j].checked = false;
count += 1;
}
}
if (count == box.length){
for (let k = 0;k < box.length;k++){
box[k].checked = true;
}
}
</script>
tweets_controller
class TweetsController < ApplicationController
before_action :authenticate_user!
def index
if params[:search] == nil
@tweets= Tweet.all
elsif params[:search] == ''
@tweets= Tweet.all
else
@tweets = Tweet.where("body LIKE ? ",'%' + params[:search] + '%')
end
if params[:genre_ids]
if params[:genre_ids]
@tweets = []
params[:genre_ids].each do |key, value|
if value == "1"
tag_tweets = Genre.find_by(name: key).tweets
@tweets = @tweets.empty? ? tag_tweets : @tweets & tag_tweets
end
end
end
end
if params[:console_ids]
@tweets = []
params[:console_ids].each do |key, value|
if value == "1"
tag_tweets = Console.find_by(name: key).tweets
@tweets = @tweets.empty? ? tag_tweets : @tweets & tag_tweets
end
end
end
if params[:genre]
Genre.create(name: params[:genre])
end
if params[:console]
Console.create(name: params[:console])
end
end
def new
@tweet = Tweet.new
end
def create
tweet = Tweet.new(tweet_params)
tweet.user_id = current_user.id
if tweet.save
redirect_to :action => "index"
else
redirect_to :action => "new"
end
end
def show
@tweet = Tweet.find(params[:id])
@comments = @tweet.comments
@comment = Comment.new
end
def edit
@tweet = Tweet.find(params[:id])
end
def update
tweet = Tweet.find(params[:id])
if tweet.update(tweet_params)
redirect_to :action => "show", :id => tweet.id
else
redirect_to :action => "new"
end
end
def destroy
tweet = Tweet.find(params[:id])
tweet.destroy
redirect_to action: :index
end
def gatya
if params[:genre_ids] or params[:console_ids]
@tweets = []
params[:genre_ids].each do |key, value|
@tweets += Genre.find_by(name: key).tweets if value == "1"
end
params[:console_ids].each do |key, value|
@tweets += Console.find_by(name: key).tweets if value == "1"
end
@tweets.uniq!
else
@tweets = Tweet.all
end
num = @tweets.length
@tweet = @tweets[rand(num)]
check = Check.new
check.list = params[:check]
check.save
@checks = Check.order(created_at: :desc).limit(1)
end
private
def tweet_params
params.require(:tweet).permit(:name, :image, genre_ids: [], console_ids: [])
end
end