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 })
                   ^            ^

知っておくべきこと: ( includesand 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
    

または吉次さんが言ったように

    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 に答える