2

私の DB では、ユーザーとロールの間に多対多の関係 ( HABTM ) があります。特定の秘書に関連付けられているユーザーのすべてのロール名を取得しようとしています。

私は次のことをまとめることができました:

class Secretary < ActiveRecord::Base
  def getRoles
    rolenames = Set.new
    Role.all.map { |role| role.users.map { |user| rolenames << role.name if user.manager.secretary == self } }
    rolenames.to_a
  end
end

...これはうまくいきますが、適切に作成された「where」ステートメントは、データベースにあまり影響を与えずに同じ結果を生成するはずです。

上記をより「ネイティブな」ActiveRecordクエリに変換することは可能ですか?

4

2 に答える 2

1

モデルを明確に把握するのに十分な情報が提供されていません。あなたが提供したものから、秘書の観点からは次のように見えると思います。

Secretary
 has_many :managers

Manager
 has_namy :users

User
 has_many :roles

深くネストされたモデルからレコードを取得するときは、ID (外部キー) の観点から考えると便利です: Rails ネストされた SQL クエリ

Rails は、where ステートメントのハッシュ バージョン内で自動的にレコードを ID に変換するため..

Role.where(:user_id => User.where(:manager_id => managers))

あなたのモデルに関する私の仮定が正しければ、あなたの答えが得られるはずです。

編集: わかりました、HABTM は水を少し濁らせます。ネストされた where を実行することはできませんが、データベースにあまり負荷をかけることなく、いくつかのマッピングと共に where を実行することはできます。これを試して:

User.includes(:roles).where(manager_id: managers).flat_map(&:roles).map(&:name)
于 2013-08-29T17:49:38.607 に答える
0

あなたのモデルは次のようです:

Role 
  has_many :users
User 
  belongs_to :role 
  has_one :manager, :class => 'User'

この場合、テーブルを内部結合するだけで、目的の結果が返されます。

SELECT roles.* FROM roles
INNER JOIN users u ON u.role_id = roles.id
INNER JOIN users m ON m.id = u.id

このクエリは、次のように変換できます。

Role.joins(:users => :manager)
于 2013-08-28T18:14:33.090 に答える