Как сделать этот SQL-запрос в Rails?

Как сделать этот SQL-запрос в Rails?

У меня есть три таблицы, к которым я пытаюсь присоединиться. Я уверен, что правильно подключил их в модели.

У меня есть несколько объединенных таблиц, в этом случае есть таблица "собственности", в которой есть идентификатор пользователя и идентификатор игры. Это внутреннее соединение с таблицей "игр" и таблицей "пользователи". В игровой таблице есть игровая информация и имеется console столбец, который соединен с консольной таблицей. Таблица консоли - это все консоли в базе данных. Таким образом, когда я показываю игру, я могу отобразить консоль, к которой она принадлежит.

Я создал веб-интерфейс, чтобы идти в ногу с моей коллекцией видеоигр. У меня это работает на PHP, но я конвертирую все в Ruby on Rails. То, что я пытаюсь сделать сейчас, - на странице инвентаризации, я хочу отображать консоли, в которых у пользователя есть игры, поэтому пользователь может выбрать консоль и фильтровать игры, отображаемые только для показа игр для этой консоли.

Например, на главной странице инвентаризации отображается каждая игра, которой владеет пользователь. На правой стороне есть боковая панель с консолями, к которой пользователь имеет игры. Если пользователь хочет видеть игры, которые у него есть для N64, он нажимает на N64, и дисплей фильтруется, чтобы показывать только игры N64.

Я не хочу отображать консоль на боковой панели, если пользователь не владеет игрой для этой консоли.

Здесь SQL-запрос, который я хочу работать:

select distinct console_general.eng_name from ownership inner join games on games.id=ownership.games_id inner join console_general on console_general.console_id=games.console_general_id;

Вот мои таблицы:

mysql> describe games;
+--------------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| ean | mediumtext | YES | | NULL | |
| eng_title | mediumtext | YES | | NULL | |
| jap_title | mediumtext | YES | | NULL | |
| console_general_id | int(11) | YES | MUL | NULL | |
| region_id | int(11) | YES | MUL | NULL | |
| image | int(11) | YES | MUL | NULL | |
+--------------------+------------+------+-----+---------+----------------+
mysql> describe ownership;
+----------------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+------------+------+-----+---------+-------+
| user_id | int(11) | NO | | 0 | |
| games_id | int(11) | YES | MUL | NULL | |
| own | *******(1) | YES | | NULL | |
| complete | *******(1) | YES | | NULL | |
| box_condition | int(11) | YES | MUL | NULL | |
| game_condition | int(11) | YES | MUL | NULL | |
| manual_condition | int(11) | YES | MUL | NULL | |
| inserts_condition | int(11) | YES | MUL | NULL | |
| notes | text | YES | | NULL | |
| spine_card_condition | int(11) | YES | MUL | NULL | |
| count | int(11) | NO | | 1 | |
+----------------------+------------+------+-----+---------+-------+
mysql> describe console_general -> ;
+------------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------+------+-----+---------+----------------+
| console_id | int(11) | NO | PRI | NULL | auto_increment |
| eng_name | text | YES | | NULL | |
| jap_name | text | YES | | NULL | |
+------------+---------+------+-----+---------+----------------+

Вот мой контроллер:

class InventoryController < ApplicationController def test # These work fine @user = User.find_by(params[:id]) @ownership = Ownership.where(user_id: 1) # This is the variable I've been working on, not sure if I'm on the right track or not. # @console = Ownership.joins(games: {console_general: :console_id}) end
end

И вот мои модели:

class Ownership < ActiveRecord::Base
self.pluralize_table_names = false
belongs_to :games
Ownership.joins(:games)
end
class Games < ActiveRecord::Base
belongs_to :console_general
belongs_to :region
belongs_to :image
has_many :ownership
Games.joins(:region, :console_general, :image)
end
lass ConsoleGeneral < ActiveRecord::Base
self.pluralize_table_names = false
has_many :games
has_many :accessories
end

Я надеюсь, что в этом есть смысл.

РЕДАКТИРОВАТЬ:

Манипулируя данным ответом, я смог его получить. Ассоциации моделей были правильными, но переменная экземпляра контроллера сначала не работала, вот что я сделал

Ownership.joins(:games => :console_general).uniq.pluck(:eng_name)

Это отлично поработало. Спасибо всем за помощь.

2 ответа

class User < ActiveRecord::Base has_many :ownerships has_many :games, through: :ownerships
end
class Ownership < ActiveRecord::Base belongs_to :user belongs_to :game
end
class Game < ActiveRecord::Base has_many :ownerships has_many :users, through: :ownerships belongs_to :console_general
end
class ConsoleGeneral < ActiveRecord::Base has_many :games
end

Railsguide

Тогда для

select distinct console_general.eng_name from ownership
inner join games ongames.id=ownership.games_id
inner join console_general on console_general.console_id=games.console_general_id

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

ConsoleGenerals.joins(:games).uniq.pluck(:eng_name)

pluck выбирает только eng_name, uniq дает "select distinct", а join (: games) заставит присутствие связанных игр.

Или это, если вы хотите ограничить принадлежащие игры

ConsoleGenerals.joins(:games => :ownerships).uniq.pluck(:eng_name)


class ConsoleGeneral < ActiveRecord::Base ... scope :with_owned_games, -> { joins(:games).merge(Games.with_ownerships) }
end
class Games < ActiveRecord::Base ... scope :with_ownerships, -> { joins(:ownership) } scope :with_certain_owner, -> { |owner_id| joins(:ownership).where(user_id: owner_id) }
end

ConsoleGeneral, которые имеют игры с собственностью:

ConsoleGeneral.with_owned_games

Только Uniq eng_names:

ConsoleGeneral.with_owned_games.select(:eng_name).uniq

ConsoleGeneral, которые имеют игры, принадлежащие пользователю с id = some_user_id:

ConsoleGeneral.with_certain_owner(some_user_id)

Только Uniq eng_names:

ConsoleGeneral.with_certain_owner(some_user_id).select(:eng_name).uniq

licensed under cc by-sa 3.0 with attribution.