カスタムロールベースの承認システムを持つ既存のRails 2.3.xアプリケーションをメンテナンスします。rails habtm:関連付けられたレコードを返しますが、排他的一致を返します
コードは次のようなものがあります。
class Role << AR:Base
# has an int attribute called "level" with higher values indicating more powerful role
habtm: members
end
class Member << AR:Base
habtm: roles
end
役割テーブルを私は以下のメンバーを持っている
(id, name, level)
1, admin, 1000
2, VIP, 500
3, regular, 100
4, some_other_role, 50
のようなものを持っています述べられた役割
MEMBER1(役割:admin
、VIP
、regular
)
member2(役割:VIP
、regular
)
member3(役割:regular
)私は時々必要なもの
は、彼らの最高の割り当てに基づいてメンバーをプルアップですロール:
Role.admins_exclusively # should return member1
Role.vips_exclusively # should return just member2
Role.regulars_exclusively # should be just member3
生のSQLクエリを書き込むことなく、Railsでこれを行う方法を頭で囲むことはできません。
提案がありますか?
更新:月29日、2012
これは、基本的にはそれぞれの役割について(よくdefine_methodと一緒にいくつかの動的なプログラミングを使用して())は、このようなメソッドの束を定義するための私のソリューションでした。
class Member < AR:Base
define_method :vips_exclusively do
scoped :joins => :roles,
:group => 'members.id',
:having => ["max(roles.level) = ?", Role.find_by_name('vip').level]
end
end
ただし、古いレール2.3.xに問題があることを発見しました。たとえば、Member.vips_exclusivelyにsize()またはcount()を呼び出すと、不正確な合計が生成されます。 length()を呼び出すと正しい結果が得られますが、可能な限りsize()を使用することをお勧めします。
Railsコードを見た後、scoped()で設定した場合、:group
と:having
のようなオプションはcount()に渡されません。スコープ付き()をnamed_scopes(アップデート:なし:)に置き換えると、カウントの問題が解決します。
私はChrisの提案と、正確さと簡潔さのためのいくつかの編集を取り入れました。ありがとうございました!
別のアップデート。
実際に:groupと:の問題は、渡されていないため、named_scoped実装にもあります。
そして、これまでにRailsソースツリー(少なくとも2.3.xブランチにはない)に修正された古いチケットがあります。
https://rails.lighthouseapp.com/projects/8994/tickets/1349-named-scope-with-group-by-bug
これは素晴らしいです...