如何在Rails中执行此SQL查询?
我有三张桌子,我试图加入。我很确定我已在模型中正确连接它们。
我有一些联合表,在这种情况下,有一个"所有权"具有用户ID和游戏ID的表。它与#34;游戏内心联系在一起。表和"用户"表。游戏表具有游戏信息,并且具有与控制台表连接的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 | tinyint(1) | YES | | NULL | |
| complete | tinyint(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)
Ownership.joins(:games => :console_general).uniq.pluck(:eng_name)
这很有效。谢谢你所有的帮助。
答案 0 :(得分:0)
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
然后
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)
答案 1 :(得分:0)
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