Thinking sphinx with privacy settings using facets? - ruby-on-rails

I'm trying to use Thinking Sphinx with my Can Can solution for authorization.
I found this answer helpful Cancan Thinking Sphinx current_ability Questions, but was wondering if there might be a way to accomplish this with facets.
So I have projects, where there is a column called privacy which is a bool. If a project is private then there is an index for collaborator_ids, which is a list of all of the users that can view the project.
I was wondering if there is a way to form a query using facets to return all projects that are either public OR private and the user's id is in the collaborator_ids.
Another approach I'm considering is formulating an extended query in my controller to check for these fields. http://sphinxsearch.com/docs/current.html#extended-syntax

I have no idea how you would do it thinking sphinx, but in normal sphinx this should work..
$cl->setSelect("*,privacy+IF(IN($user_id,collaborator_ids),1,0) AS myint");
$cl->setFilter('myint',array(1,2));
Which effectily makes an 'OR' query.
As I say, cant help you write thatin in thinging-sphinx.

Related

Find by id or by object

It's usal to see codes where a model where search in a foreign key is realized passing the whole object. For instance, search user exercises:
Exercise.where(user: user)
Another usual way to do that is:
Exercise.where(user_id: user.id)
Checking in console log, both querys search by the user id, but there is a "most recommended" way between both? If yes, why: more elegant, performatic?
I would choose the first one
Exercise.where(user: user)
It is mainly stylistic preference but also if the users every become polymorphic on exercises this would work without any changes whereas the second option would need to be changed to the first.
The benchmarks i quickly did showed no real performance difference.
Exercise.where('user_id = ?', user.id)
Not sure I understood your question correctly, but if you are looking for other ways to query or rather best practices then above is the right way to query in Rails.
The reason it is accepted as best practices is because its a Rails Security Countermeasure
Rails Guides: Array Conditions
Rails Security Guides: SQL Injections: Countermeasures
So to answer your question, yes there is good reasoning behind querying this way.

Load model partly in Ruby On rails

guys! I'm trying to make right architecture decision:
I need to hide from user of my site some fields of other users by default. So not to bother with filtering the fields in views I want to not load those fields at all, like:
default_scope -> { select(column_names - FILTERED_PARAMS) }
the rest of fields should be loaded explicitly in special cases.
The problem is that once code refers to the missing fields nomethod error shows up. I tried to meta-program those fields but fruitless this far. It seems to me that this approach doesn't fit to the AR object life-cycle.
Have you ever implemented such functionality if so what pattern have you chosen?
From my experience the best decision would be not to filter these params on the query with select, but to filter what parameters are actually sent to the user. my_model.as_json (with given param filtering options) is a simple solution for that, but for more advanced uses I would advise Rabl gem
https://github.com/nesquena/rabl
That way you have more control over which params are returned even in very advanced cases in a model-view-controller manner.

ActiveRecord: Search multiple models for a list of words

I have a search controller where I want to search a number of different models.
So say I have this query: "Foo bar baz". Then I want to have the following queries:
Model1.where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Model2.where("title like '%foo%' or title like '%bar%' or title like '%baz'").offset(o).limit(l)
Model3.joins(:sources).where("sources.name" => [source1, source2]).where("name like '%foo%' or name like '%bar%' or name like '%baz'").offset(o).limit(l)
Most important is that I want to do it safe (no SQL injections) but it would be nice if I could keep it DRY and pretty as well. I am using Rails 4 but I am very new to it. I have seen that there's something called "Concerns" which may be something to use?
Thanks!
Dependencies
You'll probably be best using one of the search extensions for Ruby stacks:
Sunspot Solr
ElasticSearch
Sphynx
As a disclaimer, I've never used any of these in production, but from my understanding, each of them will "index" data in your application, and then perform a search based on that indexed data
--
Indexing
The bottom line is if you want to search multiple models, you'll be best harnessing an index-based search system. This will take all the data you want to index, and put it into a manageable, searchable format that you can then call when you need.
As far as I know, sunspot works very well in this regard (indexing your data). The trick is to include all your models in the Sunspot settings, from which you can then pull the data you need.
There's a great Railscast about this here:
I don't have any live code for you I'm afraid - if you need more ideas, though, I'll gladly come back with them

Thinking Sphinx - Already have a search method in the model?

I'd like to use Thinking Sphinx, but I keep having problems because I have a very large rails project and the search method is used in many of my models. These already existing search methods conflict with Thinking Sphinx's search method. Is there any way around this?
I'm talking thousands of lines of code I would have to change if I had to change my search method to something else. I can't seem to find a way to change the default search method in Thinking Sphinx though either.
Thanks.
Just answered this on the TS list, but happy to answer here as well :)
There isn't any inbuilt way to do this, but in theory it could be possible. Firstly - Thinking Sphinx adds the class-level search method when you call define_index on a model - so, if you define your own search method after that, it'll overwrite the Thinking Sphinx version.
This means you could just define a new method that does the same thing - here's the code for Model.search:
def self.search(*args)
ThinkingSphinx::Search.new *search_options(args)
end
Which you could easily rename to something else:
def self.sphinx_search(*args)
ThinkingSphinx::Search.new *search_options(args)
end
The one possible catch with this is that Thinking Sphinx may have expectations internally on the search method existing and behaving as normal. I'm not sure - but give this a spin and see how you go!
Update:
As it turns out, the above suggestion doesn't cover all situations and it's still buggy. So, I think the fallback solution is to fork Thinking Sphinx, change the method names, and use your version instead of the canonical one.

Grails Indexing

How does Grails handle indexing in the database? I feel like if I try to do something like Person.findByName("KPthunder") it is going to have to search through all the records given that there is no index on the name field.
Do we have to add indexes to the columns we want to search through after grails makes the database?
All my searches are turning up are things about Grails index actions on controllers (including a search through my PDF copy of "Grails: A Quick Start Guide." I feel like I am overlooking something incredibly simple here...
Yes, we need to add indexes explicitly. They will definitely be used by DBMS, when appropriate.

Resources