一定是非常简单的事我做错了。我试图将3个表连接在一起,其中group
包含引用location_id
中的行的location
和info_id
info
。 }}
这是我的代码:
@groups = Group.joins(
'INNER JOIN location on location.id = "group".id',
'INNER JOIN info on info.id = "group".id'
)
这似乎没有错误,但我回来的只是我group
表中的列。我在这里做错了什么?
P.S。我的关联是location
和info
belongs_to group
。以及has_one
和location
info
组
答案 0 :(得分:2)
只需添加一个选择标记即可选择所需的列。
Group.joins(:location, :info).select("location.*, info.*")
如果需要一些特殊条件,你可以在课堂上添加一些。
Group.joins(:location, :info).select("location.*, info.*").where("locations.id = conditions.id")
答案 1 :(得分:1)
当您说location_id
表中有info_id
和groups
时,这意味着您打算在belongs_to
中建立Group
关联。
预备知识:
Group
模型应具有:
belongs_to :location
belongs_to :info
Location
和Info
应该有:
has_one :group
对于您的问题,这是预期的。在ActiveRecord中,Relation将返回调用者的对象,在本例中为Group
。
对于您的用例,我认为您需要这种方法才能使正确的联接工作:
查询:
@groups = Group.joins(:location, :info)
# "SELECT `groups`.* FROM `groups` INNER JOIN `locations` ON `locations`.`id` = `groups`.`location_id` INNER JOIN `infos` ON `infos`.`id` = `groups`.`info_id`"
在此之后,您可以迭代每个组以获取信息和位置,如:@groups.map { |group| [group.location, group.info] }
这将给出正确的位置和信息。
优化:[group.location, group.info]
将再次进行查询以获取位置和信息。您可以通过更改原始查询以包含位置和信息数据来优化此项:
@groups = Group.joins(:location, :info).includes(:location, :info)
答案 2 :(得分:0)
在Rails / AR中,我们有includes
和joins
。
您正在使用joins
。如SQL所示,它只选择Group
。当您需要joins
结果时,可以使用Group
,但也希望通过Location
和Info
进行查询。
如果你要使用我怀疑是你的所有信息,比如在表格中显示细节,你也应该使用includes
。
# @groups = Groups.includes(:locations, :info) results an left outer join
@groups = Groups.joins(:locations, :info).includes(:locations, :info) # results inner join
现在当你做这样的事情时,它不会进行额外的数据库调用。但是如果你使用joins
,它会使用多个查询(N + 1)。
- @groups.each do |group|
tr
td = group.id
td = group.location.lat
td = group.info.description
使用bullet gem查找是否有此类N + 1查询来优化您的项目。
如果你是Google Rails includes vs joins
,你会找到有关该主题的更多信息。
答案 3 :(得分:0)
如果您使用了此
Group.joins(:location, :info).select("location.*, info.*").where("locations.id =
conditions.id")
什么都没有改变
这是因为两个表的列名相同。