実現したいこと
Railsで楽天商品検索APIを使って、商品検索ができるアプリを作っています。
下記のような関係性を想定しており、ログインしているユーザーが、APIを叩いて表示させた商品をお気に入り登録できるようにしたいのですが、ロジックが思い浮かばず、ググってもヒントが見つからなかったのでご質問させていただきました。
そもそも外部のAPIを叩いて返ってきたデータを、テーブルに格納することはできるのでしょうか?
お手数ですが、何かヒントをいただければ幸いです。よろしくお願いいたします。
前提
単純に楽天商品検索APIを叩いて、整形して商品を画面に表示させることはできていました。
現段階ではテーブルにレコードとして入っているわけではないです。
イメージでは、表示されている商品のお気に入りボタンをクリックしたら、そのタイミングで、JSONのデータをItemsテーブルに格納して、Userと紐付けることはできないか?と考えています。
発生している問題・エラーメッセージ
該当のソースコード
search.html.slim
Ruby
1h1 楽天商品検索 2.content 3 #search-box 4 = form_with url: goods_search_path, method: :get, local: true do |f| 5 = f.text_field :keyword, class: "form-control" 6 = f.submit '検索', class: "form-control btn btn-success" 7h2 検索結果 8- if @goods.present? 9 = render 'goods/good'
_good.html.slim
ruby
1- @goods.each do |good| 2 .ui.card 3 .image 4 = image_tag good["mediumImageUrls"][0] 5 .content 6 .header 7 = good['catchcopy'] 8 .description 9 = good['itemPrice'] 10 = render 'favorites/favorite_area', good: good
_favorite_area.html.slim
ruby
1- if current_user.favorites(good) 2 = render 'favorites/unfavorite', good: good 3- else 4 = render 'favorites/favorite', good: good
_unfavorite.html.slim
ruby
1= link_to good_favorites_path(current_user.favorites.find_by(good_id: good.id)), id: "js-favorite-button-for-good-#{good.id}", method: :delete do 2 = icon 'fas', 'star'
_favorite.html.slim
ruby
1= link_to good_favorites_path(good_id: good.id), id: "js-favorite-button-for-good-#{good.id}", method: :post do 2 = icon 'far', 'star'
schema.rb
ruby
1ActiveRecord::Schema.define(version: 2020_12_30_022028) do 2 3 create_table "favorites", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t| 4 t.bigint "user_id", null: false 5 t.bigint "good_id", null: false 6 t.datetime "created_at", precision: 6, null: false 7 t.datetime "updated_at", precision: 6, null: false 8 t.index ["good_id"], name: "index_favorites_on_good_id" 9 t.index ["user_id", "good_id"], name: "index_favorites_on_user_id_and_good_id", unique: true 10 t.index ["user_id"], name: "index_favorites_on_user_id" 11 end 12 13 create_table "goods", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t| 14 t.string "name" 15 t.integer "price" 16 t.string "url" 17 t.string "image" 18 t.float "review_count" 19 t.datetime "created_at", precision: 6, null: false 20 t.datetime "updated_at", precision: 6, null: false 21 end 22 23 create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4", force: :cascade do |t| 24 t.string "name" 25 t.string "email", null: false 26 t.string "crypted_password" 27 t.string "salt" 28 t.datetime "created_at", precision: 6, null: false 29 t.datetime "updated_at", precision: 6, null: false 30 t.index ["email"], name: "index_users_on_email", unique: true 31 end 32 33 add_foreign_key "favorites", "goods" 34 add_foreign_key "favorites", "users" 35end
user.rb
ruby
1class User < ApplicationRecord 2 authenticates_with_sorcery! 3 has_many :goods, dependent: :destroy 4 has_many :favorites, dependent: :destroy 5 has_many :favorite_goods, through: :favorites, source: :good 6 7 validates :password, length: { minimum: 3 }, if: -> { new_record? || changes[:crypted_password] } 8 validates :password, confirmation: true, if: -> { new_record? || changes[:crypted_password] } 9 validates :password_confirmation, presence: true, if: -> { new_record? || changes[:crypted_password] } 10 11 validates :email, uniqueness: true 12end
good.rb
ruby
1class Good < ApplicationRecord 2 belongs_to :user 3 has_many :favorites, development: :destroy 4 5 # お気に入り追加 6 # <<で引数で渡した掲示板の情報がfavorite_goodsに入っている 7 def favorite(good) 8 favorite_goods << good 9 end 10 11 # お気に入りを外す 12 def unfavorite(good) 13 favorite_goods.delete(good) 14 end 15 16 # お気に入り登録しているか判定するメソッド 17 def favorite?(good) 18 favorite_goods.include?(good) 19 end 20end
favorite.rb
ruby
1class Favorite < ApplicationRecord 2 belongs_to :user 3 belongs_to :good 4 validates :user_id, uniqueness: { scope: :good_id } 5end
users_controller.rb
ruby
1class UsersController < ApplicationController 2 def new 3 @user = User.new 4 end 5 6 def create 7 @user = User.new(user_params) 8 if @user.save 9 redirect_to login_path 10 flash[:notice] = 'ユーザーの作成に成功しました' 11 else 12 flash.now[:alert] = 'ユーザーの作成に失敗しました' 13 render :new 14 end 15 end 16 17 def destroy 18 end 19 20 private 21 22 def user_params 23 params.require(:user).permit(:name, :email, :password, :password_confirmation) 24 end 25end
goods_controller.rb
ruby
1class GoodsController < ApplicationController 2 def search 3 if params[:keyword] 4 @goods = RakutenWebService::Ichiba::Item.search(keyword: 'ギフト' + params[:keyword], giftFlag: 1) 5 end 6 end 7 8 def favorites 9 @favorite_goods = current_user.favorite_goods.includes(:user).order(created_at: :desc) 10 end 11end
favorites_controller.rb
ruby
1class FavoritesController < ApplicationController 2 3 def create 4 good = Good.find(params[:good_id]) 5 current_user.favorite(good) 6 redirect_back fallback_location: root_path, success: 'お気に入りに登録しました' 7 end 8 9 def destroy 10 good = current_user.favorites.find_by(params[:id]).good 11 current_user.unfovorite(good) 12 redirect_back fallback_location: root_path, success: 'お気に入りを外しました' 13 end 14end
routes.rb
ruby
1Rails.application.routes.draw do 2 get 'login', to: 'user_sessions#new' 3 post 'login', to: 'user_sessions#create' 4 delete 'logout', to: 'user_sessions#destroy' 5 root 'users#new' 6 7 resources :users, only: %i(new create) 8 get 'goods/search' 9 10 resources :goods, shallow: true do 11 resource :favorites, only: %i(create destroy) 12 collection do 13 get :favorites 14 end 15 end 16end
補足情報(FW/ツールのバージョンなど)
Ruby 2.7.2
Rails 6.0.3.4
楽天商品検索API
あなたの回答
tips
プレビュー