2011-07-07 8 views
2

cancanをスフィンクスと思って作業しようとしましたが、いくつかの問題が発生しました。Cancan Thinking Sphinxについての最新の質問

スフィンクスを使用する前に、私は私の会社でこれを持っていたビュー:誰の企業を見てから、私のユーザーを防止

@companies = Company.accessible_by(current_ability) 

...

スフィンクスをインストールした後、私は終わった:

@companies = Company.accessible_by(current_ability).search(params[:search], :include => :order, :match_mode => :extended).paginate(:page => params[:page]) 

これは私のすべての企業を表示し、能力に基づいてユーザーごとに洗練されていません。

cancanにtsが設定されていないことがわかりますか?

答えて

3

おそらくaccessible_byがスコープであると思われます。これはデータベース/ SQL駆動型です。 Sphinxには独自のクエリインタフェースがあるため、ActiveRecordスコープは適用されません。

非効率的な回避策は、(最初​​にすべての企業を取得します):

company_ids = Company.accessible_by(current_ability).collect &:id 
@companies = Company.search params[:search], 
    :include => :order, 
    :match_mode => :extended, 
    :page  => params[:page], 
    :with  => {:sphinx_internal_id => company_ids} 

注意すべき物事のカップル:sphinx_internal_idは、インデックス付きのモデルの主キーである - スフィンクスは、したがって区別、IDという名前の独自のユニークな識別子を持っています。また、paginateを検索コレクションに呼びたくない場合 - スフィンクスは常にページ番号を付けますので、:pageパラメータを検索呼び出しに渡すだけです。

スフィンクスに相当するaccessible_by相当の情報があり、関連情報がインデックスとしてインデックスに追加されているか、理想的ではないとしても簡単な場合は会社のIDを取得すればよい上のスニペットの最初の行に返され、はすべての会社をActiveRecordオブジェクトとしてロードしません。どちらもCancanのヘルパーをバイパスしたり複製したりすることを意味します。

多分これは、後者のアプローチを取って、トリックを行うだろう...けれども:

sql   = Company.accessible_by(current_ability).select(:id).to_sql 
company_ids = Company.connection.select_values sql 
@companies = Company.search params[:search], 
    :include => :order, 
    :match_mode => :extended, 
    :page  => params[:page], 
    :with  => {:sphinx_internal_id => company_ids} 

は不要会社のオブジェクトをロードする、カンカンヘルパーを使用して回避し、きちんと動作します(これは/スコープを返す提供されます) Sphinx/Thinking Sphinxが何を期待しているのか。私はCancanを使用していないので、これはちょっとした推測です。

+0

私はあなたのアプローチを消化してみましょう。 –

+0

に時間を割いていただき本当にありがとうございます。Ryan Bates(Cancanの著者)は、accessible_byがスコープであることを確認しました。最終的な解決策はそのトリックを行うべきです。任意の質問は、私に知らせてください:) – pat

+0

SQLをthinking_sphinxに直接渡す方法はありますか?この解決策はすばらしいですが、company_ids配列が大きくなった場合、スケーリングに問題があるようです。 – Cyrus

関連する問題