我需要从我的数据库中获取非工作人员的所有用户:
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的dev不会给我这个错误) :
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)
答案 0 :(得分:4)
要让所有用户与员工无关,您可以使用以下内容:
User.includes(:staff).where(staff: { id: nil })
对于以下查询“获取所有没有用户关联的员工”,它的工作方式相同:
Staff.includes(:user).where(users: { id: nil })
^ ^
要知道的事情:在includes
(以及preload
和joins
)方法中,您必须使用模型中定义的关系名称({ {1}}&amp; belongs_to
:singularize,has_one
:pluralize),但在where子句中你必须使用关系的复数版本(实际上,表格是名称)。
答案 1 :(得分:0)
你有3个解决方案:
做一些没有优化和肮脏的事情,如:
User.where('id NOT IN(?)', Staff.select(:user_id).all.map(&:user_id).uniq).all
User.includes(:staff).where(:staff => {:id => nil})
向您的表用户添加一个字段,以了解您的用户是否有员工,因此您必须在为用户创建员工后将此字段设置为true,但您可以轻松地让所有用户
User.where(:have_staff => false).all
或者您反转您的关系并说工作人员has_one用户和用户belongs_to工作人员并获取您所有用户
User.where(:staff_id => nil).all