はじめに
今日も投稿いたします!最近は投稿することに楽しみを覚えてきました^^
某プログラミングスクールの最終課題で某フリマアプリのクローンにて、商品出品後の一覧表示が大変だった件について投稿いたします。indexの部分になります。
結論は
instance_variable_setメソッド
を使用いたしました。こちらは変数名を変えて繰り返し使いたいメソッドになります。
当初はレディースごと、メンズごとに変数を定義していたのですが、
「じゃあカテゴリーが増えた時は、またいちいち変数を定義しないといけないのか」
というメンテナンス性に欠けておりスマートではなかったので、リファクタリングも込みで修正することにいたしました。
これが商品出品後に
こうなればいいでヤンスね!
前提条件
- ancestryでのカテゴリー階層化が終わっている
- carrierwaveでの複数画像投稿が終わっている
もし、複数画像投稿が終わっていない場合は
【Ajax+Rails+Carrierwave】個別削除可能な画像複数(10枚まで)投稿
をご覧ください。
テーブルの関係
商品テーブル:画像テーブル=1:多
1つの商品は複数の画像を持っている
商品テーブル:カテゴリテーブル=1:多
1つの商品は複数カテゴリー(3階層先まで)をもっている
controllerでの記述
class GoodsController < ApplicationController
before_action :index_brand_set, only: :index
private
def index_category_set
array = [1, 2, 3, 4]
for num in array do
search_anc = Category.where('ancestry LIKE(?)', "#{num}/%")
ids = []
search_anc.each do |i|
ids << i[:id]
end
goods = Good.where(category_id: ids).order("id DESC").limit(10)
instance_variable_set("@cat_no#{num}", goods)
end
end
私の場合はprivateの中に書いてしまい、before_actionでindexに呼び出ししました!
1ずつ解説していくと
array = [1, 2, 3, 4]
for num in array do
arrayという配列に1, 2, 3, 4を入れてnumという変数に順番に放り込んでいます。
search_anc = Category.where('ancestry LIKE(?)', "#{num}/%")
そしてsearch_ancでカテゴリーを絞っていくわけですが、Categoryテーブルのancestryカラムで、
先ほど、numに格納していた1(メンズ),2(レディース),3(家電),4(おもちゃ)ごとに取り出します。
おいおいsyomaさん。3階層も取り出せたの!?ご安心を!
"#{1}/%"
の場合、レディースに関連しているもの(idの5~13)をすべてひっぱり出せます。
ids = []
search_anc.each do |i|
ids << i[:id]
そしてidsという配列の中に先ほど抽出したCategoryテーブルのidを入れてます。
goods = Good.where(category_id: ids).order("id DESC").limit(10)
instance_variable_set("@cat_no#{num}", goods)
goodsという変数の中にGoodテーブルで先ほど絞ったcategory_idをもつ商品を抽出し、降順の10個まで表示できるようにしております。
最後のinstance_variable_setで
"@cat_no#{1}",@cat_no#{2}",@cat_no#{3}",@cat_no#{4}"
と複数展開できるわけです。
ここで私は1つの疑問を抱きます。
「画像は!?」
ご安心を!
has_manyの関係があれば(リレーションを張っていれば)viewの方で簡単に引っ張ってこれまする^^
viewでの記述
レディースで表示させてみましょう!
.main__contents__center__item__ladies__image
%ul.main__contents__center__item__ladies__image__ul
- @cat_no1.each do |good|
%li.main__contents__center__item__ladies__image__ul__li
.main__contents__center__item__ladies__image__ul__li__top-image
= link_to good_path(good.id) do
= image_tag "#{good.photos[0].image.url}"
%area-label
= "¥#{good.fee}"
.main__contents__center__item__ladies__image__ul__li__under-text
%span
= good.name
こんな感じ。1つずつ見ていきましょう!
- @cat_no1.each do |good|
ではgoodという変数に先ほど、抽出したレディースを格納しています。
= link_to good_path(good.id) do
こちらはshowへ飛ぶリンクなので気にせずに。
= image_tag "#{good.photos[0].image.url}"
こちらで画像を引っ張るわけですが
変数.テーブル名s[0].カラム名.url
ですね!先ほど作成したgoodという変数に紐づいているphotoテーブルのimageカラムをひっぱり出しています。
テーブル名が複数形になっているのはhas_manyの関係だからです。
[0]は配列に入っている1番目の画像を引っ張っております。
メンズの場合
- @cat_no2.each do |good|
@cat_no2に変更して同じように展開するんだぁーーーーーーーーーーーーーー
ブランドは!?
privateの中に別で書いてみてください!
要領をご理解いただければ同じように展開できます。
以上です!
最後に
twitterやっておりますので是非フォローよろしくお願いいたします。
https://twitter.com/syomabusiness
youtubeも始める予定です。