如何在 rails 活动模型上构建 select cmd?

How to build select cmd on rails active model?

用户Table

id| name  | email          | invited_by_id  
1 | jhon  | jhon@mail.com  | null  
2 | sarah | sarah@mail.com | 1  
3 | baby  | baby@mail.com  | 2  

作为用户 table,您将看到 sarah 受 jhon 邀请,baby 受 sarah 邀请

期待结果

id| name  | email         | invited_by_id | invited_by_name  
1 | jhon  | jhon@mail.com | null          | null  
2 | sarah | sarah@mail.com| 1             | jhon  
3 | baby  | baby@mail.com | 2             | sarah 

如何创建 select cmd 或在 rails 活动模型上获得我期望的结果的最佳方法?

user.rb

def inviter_name
  if self.invited_by_id.nil?
    nil
  else
    User.find(self.invited_by_id).name
  end
end

或者您可以使用 belongs_to

belongs_to :inviter, class_name: "User", foreign_key: 'invited_by_id'

邀请人姓名如下:

@user.inviter.name

@Zoker 是正确的,您应该在模型定义中添加一个 'belongs_to' 子句:

belongs_to :invited_by, class_name: "User"

完成后,请求可以像这样简单:

User.all.each do |user|
  puts [user.name, user.email, user.invited_by_id.to_s, user.invited_by.name].join(", ")
end

这将打印出您需要的结果的(非常)基本的 CSV 列表。这在控制台会话中最有意义 - 如果您将此代码放在控制器中,您最终会在服务器输出中丢失它。

对于大型列表,使用此查找会降低性能。对于每一行,将向数据库发出单独的请求以查找 'invited by' 用户,以便我们可以读取名称。

更好的做法是:

User.includes(:invited_by).each do |user|
  puts [user.name, user.email, user.invited_by_id.to_s, user.invited_by.name].join(", ")
end

这告诉 Rails 再进行一次查询,一次性获取所有包含的 'invited_by' 用户。这意味着您现在只需进行 2.

次查询,而不是进行 (number_of_rows + 1) 次查询

(代码在撰写本文时未经测试。)