Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is there a way to mix rails named scopes and thinking sphinx scopes?

Is there a way to mix named scopes and sphinx scopes? I can't believe there's not.

I have sphinx index on Lessons. Once users purchase lessons, they have a screen that they can see a list of all of their lessons. I want them to perform the same searches they can on site-wide lessons, but scoped to the ones they own.

This is obviously not possible with sphinx-only scopes, because I'm not indexing the purchasing data, nor do I think I should have to.

Is there any way to accomplish this?

This is what I have so far to "combine" the two systems. It seems hackish to me but it works:

lesson_ids = current_user.active_products_by_type(:lessons).collect{|x| x.id}
@lessons = Lesson.active_scope.search :with => {:id => lesson_ids }
like image 758
pixelearth Avatar asked Oct 06 '11 18:10

pixelearth


People also ask

What is a named scope in Rails?

In Ruby on Rails, named scopes are similar to class methods (“class. method”) as opposed to instance methods (“class#method”). Named scopes are short code defined in a model and used to query Active Record database.

What is named scope?

What is a named scope? A named scope is simply a class method inside of your model that always returns an active record association. Imagine this application: we have a database of shirts and we want to return all of the shirts that are red.


2 Answers

It's a bit hard to tell whether your work-around is appropriate, given I'm not sure what the scopes active_products_by_type and active_scope are (which is the Sphinx one? Both? Neither?).

But you cannot call an AR scope on a search call, because AR scopes are built under the hood to generate SQL queries. Sphinx has its own querying protocol, which is why Thinking Sphinx added Sphinx scopes. Added to that is that Sphinx can't reference the database while searching (only while indexing), so any reference to data that Sphinx can't see is not going to be helpful either.

All that said, there's probably nothing in the code that will let you chain a search call onto an AR scope - and you will likely even get results back - but this is because the scope affects the Model.find call that Thinking Sphinx makes to convert search results into model instances. The upshot is that while you may see objects, the AR scope is only being applied to the given page of search results, and the pagination math (number of pages/total results) will be unreliable.

Urgh, that turned into a bit of an essay, but hopefully it helps...

like image 194
pat Avatar answered Sep 25 '22 20:09

pat


I guess it's better to end with AR scopes to be able to do .includes, .joins etc:

sphinx_scope(:visible) do
  { with: {is_visible: true} }
end

@items = Item.where(
  id: Item.visible.search_for_ids(nil,
    page: params[:page],
    with: {
      tag_id: @tag.id,
      category_id: current_category.id
    }
  )
).order(:id).includes(:photos)
like image 29
Dennis Krupenik Avatar answered Sep 21 '22 20:09

Dennis Krupenik