#はじめに
ポートフォリオを作成していく中で楽天APIのデータをテーブルに保存したいと思い探すと以下の記事を見つけました
https://qiita.com/Hiroaki_jr/items/983b11a45e2b42c8f3dc
こちらの記事を参考に自分なりに改良してコードを書き直したので誰かの参考になればと思い書かせていただきます。
#環境
ruby 2.6.5
rails 6.0.3
mysql 8.0.23
#ER図
ユーザー(Userモデル)がアイテム(Rakutenモデル)を購入したいリストとして登録(Buylistモデル)できるようなアソシエーションを作りました。
例としてはユーザーが投稿に対していいねができるのようなアソシエーションと同じだと思います。
Rakutenのカラムはjsonで送られてくるデータの中で必要なデータをカラムとして作成しました
#Controller
テーブルの作成、ルーティングの記述、モデルのアソシエーションの設定は割愛させていただきます。
主にコントローラー、ビューの部分の記述を説明させていただきます。
def index
#長いためprivetメソッドに定義
create_rakuten_data(params)
@items = Rakuten.all.page(params[:page])
# 全アイテム数
@total_count = @results.response.count
end
def search
@items = @q.result.page(params[:page]).per(30)
@count = @q.result.count
end
private
#楽天市場の店指定のアイテムを取得
def create_rakuten_data(params)
@results = RakutenWebService::Ichiba::Item.search(
shopCode: 'shop-senjin',
page: params[:page],
hits: 30)
#ここで取得したアイテムをテーブルに保存するがすでに保存されているアイテムは保存しない処理を行う
@results.each do |result|
#取得したデータの配列のresultを引数にprivetメソッドreadを呼び出し
item = Rakuten.new(read(result))
#rakutensテーブルに同じアイテムがあれば保存しない処理
unless Rakuten.all.exists?(item_name: item.item_name)
item.save
end
end
end
def read(result)
#Rakutenモデルのインスタンスに埋め込む
image_url = result['mediumImageUrls'][0]
item_name = result['itemName']
item_price = result['itemPrice']
item_url = result['itemUrl']
shop_name = result['shopCode']
genre_id = result['genreId']
review_average = result['reviewAverage']
{
image_urls: image_url,
item_name: item_name,
item_price: item_price,
item_url: item_url,
shop_name: shop_name,
genle_id: genre_id,
review_average: review_average
}
end
楽天APIで取得したBooksデータには一意なカラム「isbn」があるが、Itemには一意なカラムがないためitem_nameを一意のカラムとして扱いました。
#View
.senjin-search
= search_form_for @q, url: search_rakutens_path do |f|
.text-center.my-3
%h4.my-2.font-weight-bold キーワード検索
= f.search_field :item_name_or_item_price_cont, class: 'senjin-field'
= button_tag type: 'submit', class: 'icon senjin-icon' do
%i.fas.fa-search
.text-center.my-3
%h4.my-2.font-weight-bold ジャンル検索
= f.select :genle_id_eq, {'バッグ、ポーチ、入れ物': 213693, 'バックパック,リュック': 111926, '手袋': 509058, '靴下': 408907, '小物,装具': 213694, 'Tシャツ': 551180, 'コンパス': 208078, 'GPS': 402305, 'サングラス、ゴーグル、フェイスフード': 213692, 'クッション、ベッド部品': 111925, 'ビニールテープ': 301594, 'ジャケット': 558873, '身分証入れ': 403809, 'トレーニングウェア': 302491, 'マット類': 501931}, { include_blank: '指定なし'}, class: 'senjin-field'
= button_tag type: 'submit', class: 'icon senjin-icon' do
%i.fas.fa-search
.senjin-counts
全アイテム数: #{@total_count} 件
.container
.row
= render 'commons/rakuten_item', items: @items
= paginate @items
- items.each do |item|
.col-sm-4.col-md-4.col-lg-3.col-xl-2.mb-3
.senjin-item.mx-auto
.api-img
= link_to item.item_url do
= image_tag item.image_urls
.api-content
= item.item_name
.api
.api-title
購入金額
.api-value
#{item.item_price}円
.api
.api-title
平均評価
.api-value
#{item.review_average}
.buy-list.mt-2
- if current_user.has_buylist?(item)
.not-buy#unfollow-btn
= link_to '購入リストから解除', rakuten_buylist_path(item), method: 'delete',class: 'rakuten-delete'
- else
.buy#follow-btn
= link_to '購入リストに登録', rakuten_buylist_path(item), method: 'post',class: 'rakuten-post'
以上でざっくりですが説明を終わらせていただきます。
何かご質問や不備な点などあればコメントいただきたいです