Cancan Thinking Sphinx current_ability Questions

旧巷老猫 提交于 2019-12-03 21:22:35

I think it's more that accessible_by is probably a scope - which is Database/SQL-driven. Sphinx has its own query interface, and so ActiveRecord scopes don't apply.

An inefficient workaround (gets all companies first):

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}

A couple of things to note: sphinx_internal_id is the indexed model's primary key - Sphinx has its own unique identifier named id, hence the distinction. Also: You don't want to call paginate on a search collection - Sphinx always paginates, so just pass the :page param through to the search call.

There'd be two better workarounds that I can think of - either have a Sphinx equivalent of accessible_by, with the relevant information added to your indices as attributes - or, simpler if not quite as ideal, just get the company ids returned in the first line of my above snippet without loading up every company as an ActiveRecord object. Both will probably mean bypassing and/or duplicating Cancan's helpers.

Although... maybe this would do the trick, taking the latter approach:

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}

Avoids loading unnecessary Company objects, uses the Cancan helper (provided it is/returns a scope), and works neatly with what Sphinx/Thinking Sphinx expects. I've not used Cancan though, so this is a bit of guesswork.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!