Cancan Thinking Sphinx current_ability Questions

倖福魔咒の 提交于 2019-12-05 04:48:29

问题


trying to get cancan working with thinking sphinx but running into some issues.

Before using sphinx, I had this in my companies view:

@companies = Company.accessible_by(current_ability)

That prevented my users from seeing anyone else's companies...

After installing sphinx, I ended up with:

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

Which now displays all my companies and isn't refining per user based on ability.

It would see ts isn't set up for cancan?


回答1:


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.



来源:https://stackoverflow.com/questions/6610426/cancan-thinking-sphinx-current-ability-questions

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