LoginSignup
2
7

More than 3 years have passed since last update.

【Rails+Ancestry+Carrierwave】商品一覧表示〜出品した複数の画像から最初の1枚を添えて〜

Last updated at Posted at 2020-03-07

はじめに

今日も投稿いたします!最近は投稿することに楽しみを覚えてきました^^

某プログラミングスクールの最終課題で某フリマアプリのクローンにて、商品出品後の一覧表示が大変だった件について投稿いたします。indexの部分になります。

結論は

instance_variable_setメソッド

を使用いたしました。こちらは変数名を変えて繰り返し使いたいメソッドになります。
当初はレディースごと、メンズごとに変数を定義していたのですが、
「じゃあカテゴリーが増えた時は、またいちいち変数を定義しないといけないのか」
というメンテナンス性に欠けておりスマートではなかったので、リファクタリングも込みで修正することにいたしました。

スクリーンショット 2020-03-07 10.18.31.png

これが商品出品後に

スクリーンショット 2020-03-07 10.10.29.png

こうなればいいでヤンスね!

前提条件

  1. ancestryでのカテゴリー階層化が終わっている
  2. carrierwaveでの複数画像投稿が終わっている

もし、複数画像投稿が終わっていない場合は

【Ajax+Rails+Carrierwave】個別削除可能な画像複数(10枚まで)投稿

をご覧ください。

テーブルの関係

商品テーブル:画像テーブル=1:多
1つの商品は複数の画像を持っている

商品テーブル:カテゴリテーブル=1:多
1つの商品は複数カテゴリー(3階層先まで)をもっている

controllerでの記述

goods_controller.rb
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ずつ解説していくと

goods_controller.rb
 array = [1, 2, 3, 4]
  for num in array do

arrayという配列に1, 2, 3, 4を入れてnumという変数に順番に放り込んでいます。

goods_controller.rb
 search_anc = Category.where('ancestry LIKE(?)', "#{num}/%")

そしてsearch_ancでカテゴリーを絞っていくわけですが、Categoryテーブルのancestryカラムで、
先ほど、numに格納していた1(メンズ),2(レディース),3(家電),4(おもちゃ)ごとに取り出します。
おいおいsyomaさん。3階層も取り出せたの!?ご安心を!

"#{1}/%"

の場合、レディースに関連しているもの(idの5~13)をすべてひっぱり出せます。

スクリーンショット 2020-03-07 10.33.57.png

goods_controller.rb
 ids = []
  search_anc.each do |i|
   ids << i[:id]

そしてidsという配列の中に先ほど抽出したCategoryテーブルのidを入れてます。

goods_controller.rb
 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での記述

レディースで表示させてみましょう!

index.html.haml
.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つずつ見ていきましょう!

index.html.haml
- @cat_no1.each do |good|

ではgoodという変数に先ほど、抽出したレディースを格納しています。

index.html.haml
= link_to good_path(good.id) do

こちらはshowへ飛ぶリンクなので気にせずに。

index.html.haml
= image_tag "#{good.photos[0].image.url}"

こちらで画像を引っ張るわけですが

変数.テーブル名s[0].カラム名.url

ですね!先ほど作成したgoodという変数に紐づいているphotoテーブルのimageカラムをひっぱり出しています。
テーブル名が複数形になっているのはhas_manyの関係だからです。
[0]は配列に入っている1番目の画像を引っ張っております。

メンズの場合

index.html.haml
- @cat_no2.each do |good|

@cat_no2に変更して同じように展開するんだぁーーーーーーーーーーーーーー

ブランドは!?

privateの中に別で書いてみてください!
要領をご理解いただければ同じように展開できます。

以上です!

最後に

twitterやっておりますので是非フォローよろしくお願いいたします。
https://twitter.com/syomabusiness
youtubeも始める予定です。

2
7
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
2
7