3

我需要从我的数据库中获取所有不是员工的用户:

class User < ActiveRecord::Base
  has_one :staff
  def is_staff?
    staff != nil
  end
end
class Staff < ActiveRecord::Base
  attr_accessible :user_id
  belongs_to :user
end

所以我可以在代码中做到这一点:

User.all.select {|user| not user.is_staff? }

这似乎可行,但我想在数据库中有这个逻辑,而且我在尝试以这种方式排序时由于某种原因在使用 Heroku 的生产中出错(使用 sqlite 的开发人员不会给我这个错误):

NAME_SORT = ->(a, b) {
  if a.first_name == b.first_name
    a.last_name <=> b.last_name
  else
    a.first_name <=> b.first_name
  end
}
User.all.select {|user| not user.is_staff? }.sort &NAME_SORT

由于某种原因,我得到的错误是:

ArgumentError: comparison of User with User failed

无论如何,如果我想获得所有员工用户,这似乎很简单:

User.joins(:staff)

有没有一种简单的方法可以让不是员工的用户?也许是这样的?

User.not_joins(:staff)

而且我真的需要用户不是员工或管理员:

User.not_joins(:staff, :admin)
4

2 回答 2

4

要获取与员工没有关系的所有用户,您可以使用以下命令:

User.includes(:staff).where(staff: { id: nil }) 

对于以下查询“获取没有关联用户的所有员工”,它的工作方式相同:

Staff.includes(:user).where(users: { id: nil })
                   ^            ^

要知道的事情:includes(and preloadand joins) 方法中,您必须使用模型中定义的关系名称(belongs_to& has_one:单数化,has_many:复数),在 where 子句中,您必须使用关系的复数版本(实际上,表的名称)。

于 2013-08-15T13:12:03.363 回答
0

您有 3 个解决方案:

  • 做一些没有优化和肮脏的事情,比如:

    User.where('id NOT IN(?)', Staff.select(:user_id).all.map(&:user_id).uniq).all
    

或者像 Yoshiji 先生说的

    User.includes(:staff).where(:staff => {:id => nil})
  • 为您的表用户添加一个字段,以了解您的用户是否有员工,因此您必须在为用户创建员工后将此字段设置为 true,但您可以轻松获取所有用户

    User.where(:have_staff => false).all
    
  • 或者您颠倒您的关系并说 Staff has_one User 和 User belongs_to Staff 并获得所有用户

    User.where(:staff_id => nil).all
    
于 2013-08-14T21:49:36.863 回答