Добавление содержимого с одного контроллера в индекс другого контроллера

#ruby-on-rails #api #model-view-controller

#ruby-on-rails #API #модель-представление-контроллер

Вопрос:

Моя цель — чтобы пользователи добавляли отдельные игры, извлеченные из API gem (https://github.com/games-directory/api-giantbomb ) в их личную библиотеку. Я хочу, чтобы пользователи могли просматривать библиотеки других людей. У меня игры отображаются через поиск вместе со страницей показа для каждой игры.

Я сталкиваюсь с двумя проблемами: не могу добавлять игры в библиотеку пользователя и не могу просматривать библиотеки других людей.

Вот мой игровой контроллер:

 class GamesController < ApplicationController

#search for games
  def index
  @games = GiantBomb::Search.new().query(params[:query]).resources('game').limit(100).fetch
  end

#Shows data for individual games
  def show
  @game = GiantBomb::Game.detail(params[:id])
  end

#Adding and removing games to a user's library
  def library
    type = params[:type]
    @game = GiantBomb::Game

    if type == "add"
      current_user.library_additions << @game
      redirect_to user_library_path, notice: "Game was added to your library"

    elsif type == "remove"
      current_user.library_additions.delete(@game)
      redirect_to root_path, notice: "Game was removed from your library"
    else
      # Type missing, nothing happens
      redirect_to game_path(@game), notice: "Looks like nothing happened. Try once more!"
    end
  end


private

  def game_params
    params.require(:game).permit(:name, :search, :query)
  end
end
 

Когда я пытаюсь добавить игру в свою библиотеку, я получаю «Ожидаемая игра (# 70231217467720), получена GiantBomb::Game, которая является экземпляром класса (#70231150447440)». Итак, мой @game неверен, но я не уверен, что должно быть там вместо этого.

Даже если бы я мог добавить игру в свою библиотеку, я не могу просматривать библиотеки других пользователей. Вот мой текущий контроллер.

 class LibraryController < ApplicationController
  #before_action :authenticate_user!

  def index
    @library_games = User.library_additions
  end
end

 

Я получаю «неопределенный метод library_additions», даже если он есть в модели. Если я сменю User на current_user, я смогу увидеть страницу, но это означает, что пользователи могут видеть только свою страницу, а не другие.

Вот моя модель игры, пользователя и библиотеки:

 class Game < ApplicationRecord
has_many :libraries
has_many :added_games, through: :libraries, source: :user
end
 
 class User < ApplicationRecord

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
  has_many :games
  has_many :libraries
  has_many :library_additions, through: :libraries, source: :game
end
 
 class Library < ApplicationRecord
  belongs_to :game
  belongs_to :user
end
 

I made my library a join table for users and games but I am thinking I didn’t do it correctly. Here is my schema:

 ActiveRecord::Schema.define(version: 2020_11_19_143536) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "games", force: :cascade do |t|
    t.string "name"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.string "search"
  end

  create_table "libraries", force: :cascade do |t|
    t.integer "user_id"
    t.integer "game_id"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
  end

end
 

Я пропускаю миграцию или мне нужно переделать модели и контроллеры?

[править] Вот мои маршруты, я получаю сообщение об ошибке при попытке добавить игру.

 Rails.application.routes.draw do
  devise_for :users
  resources :games do
    member do
      put "add", to: "games#library"
      put "remove", to: "games#library"
    end
  end
  resources :library, only:[:index]
  root to: 'pages#home'
  get '/search', to: 'games#search', as: :search
  get '/games', to: 'games#index', as: :index
  get '/user/:id', to: 'user#show'
  get '/user/:id/library', to: 'library#index', as: :user_library
end
 

Ответ №1:

Здесь в ошибке четко указано, что ожидается экземпляр Game not GiantBomb::Game , поэтому вам нужно его создать.

 @game = Game.new(name: 'some name', other fields ....)

if type == "add"
  current_user.library_additions << @game
 

О другой ошибке вы можете вызывать методы ассоциации только для экземпляра, а не для самого класса

 def index
  # You could get the user'id through params for example
  @library_games = User.find(params[:user_id]).library_additions
end