新手问题 Rails 中的 Model 查询问题 [已解决]

sixther · April 10, 2016 · Last by sixther replied at April 11, 2016 · 3651 hits

def index
    @host=Host.all   #可以转换下host,加上groupname字段,虚拟model? 

如代码,我有两个表 hosts,groups,如何可以在 view 中显示 hosts 表中的 group_id 对应的 groupname?

新手,求答疑。

hosts 和 groups 的关系是:host belong_to group并且group has_many hosts ?
所以首先你应在对应 model 里面定义好两者的关系。
然后在 controller 对应的 action 中使用 @hosts = Group.includes(:hosts)

Group.includes(:hosts) 可写在 model 的 scope 中方便调用。

接着你在视图中 each

#假设你使用了 haml 模板渲染视图
- @hosts.find_each do |h|
  = h.group.name

你试试看,最后建议你多翻一下 Ruby on Rails guides

@hww 你这里应该用 Group.includes(:hosts)

@killernova 👍 ,已修正。

11 更,之前我被你这么一说把 joins 和 includes 弄混淆了。楼主要得到 Hosts 对象呢。

@hww @killernova 多谢二位的热心回答,我查了下官方文档,includes 与之关联的对象加载进来,确实满足我的需求。 世界上我就是想在数据库中执行如下语句:

elect hosts.*,groupname from hosts JOIN groups on hosts.group_id=groups.id;

然后对象的 action 应该是:

@host=Host.joins('LEFT JOIN groups on hosts.group_id=groups.id') 

但是这种方法得不到 groups 里面的任何字段,然后可以加上 includes 再试试:

@host=Host.joins('LEFT JOIN groups on hosts.group_id=groups.id').includes(:groups)
@host=Host.includes(:groups)

可是无论是怎么使用 includes,最终都会报错:

uninitialized constant Host::Groups

@hww @killernova 没有找到可以直接查询到同时包含两个表的字段的方法,倒是找到了一个比较笨的方法:

def index 
    @host=Host.all
    @group=Group.all

然后 view 这里:

<td><%= @group.find(host.group_id).groupname %></td>    #host为@host其中的一个元素.

#5 楼 @sixther

#1 是正解。

@group = Group.includes(:hosts) 

这里可以通过,Group.includes(:hosts).to_sql 来查看是执行了两条。

你的写法也是可以实现的。只是会出现多次重复查询的问题。在 index 里面的时候会查询两次,在 view 更是会多次。这个看日志会更清晰。

一楼正解,避免了 n+1

#5 楼 @sixther 这个问题很基础,建议先去看看入门例子http://guides.rubyonrails.org/getting_started.html,另外要注意的是,尽量不要把数据库查询写在 view 层,http://liuzxc.github.io/articles/rails-common-mistakes/

#6 楼 @awking 嗯,看到了,确实执行了两个 sql,

Group Load (0.2ms)  SELECT "groups".* FROM "groups"
Host Load (0.2ms)  SELECT "hosts".* FROM "hosts" WHERE "hosts"."group_id" IN (1, 2)

可是,这个时候的@groups是 Group 的集合,我该怎么得到 Host 的集合呢。 includes 应该是用在两个表之间的联合查询,比如查找特定 groups 里的所有 hosts,我是想如何在 view 中得到与 hosts 相关联的 groups 表的某些字段。

#7 楼 @riskgod 1#确实牛逼,说的这个方法我现在还没参透呢,😅

#8 楼 @linyunjiang 嗯,多谢,我也觉得 view 里写查询不好,可是这不是刚入门嘛,就先瞎试呢,看看都能干嘛。 多谢你的分享哈。

@sixther 之前我写的有错误。
要得到 Host 集合应这样搞:@hosts = Host.joins(:groups)
然后要在 view 中得到你要的 group name,遍历 @Hosts 对象时类似这样显示:h.group.name
具体关于includesjoins方法使用请查看文档吧。
active_record_querying

#12 楼 @hww 😓,终于找到原因了

class Host < ActiveRecord::Base
    has_many :comments
    belongs_to :group
end

我这里以前写的是 belongs_to :groups,然后 h.group.name 的时候一直不出来东西。 原来 belongs_to 后面的需要单数。😓 这块属于什么概念,怎么才能理解它呢。

就是说 rails 创建 model 的时候都是以单数的形式去创建的,然后给建一个复数名字的数据表,然后维护表与表之间的关系也需要注意单复数,确实很贴切英语语法😓

You need to Sign in before reply, if you don't have an account, please Sign up first.