Hi Pat,
I've now implemented a solution, not sure if this is the best way but
it seems to work pretty well.
I added a new field to the projects table called search_access_tag,
this is a string field that has the following structure
"#{project_type_id}-#{client_id}", then I make sure this is created
after save each time.
Then add it to the ts index as:
has search_access_tag
Then in the search I do:
access_tags = ProjectAccess.find(:all, :conditions => {:user_id =>
current_user.id}).collect { |access| access.search_access_tag } #
Where the identical string access_tags are created from the
project_type_id and client_id for that user
@search_results = ThinkingSphinx.search params[:search], :page =>
params[:page], :retry_stale => true, :order
=> :created_at, :sort_mode
=> :desc, :with=>{:search_access_tag=>access_tags}
This all works roughly as expected and seems to be fast.
Until I try this for testing I have a problem:
1. access_tags = [] # Empty, hoping for 0 results
@search_results = ThinkingSphinx.search params[:search], :page =>
params[:page], :retry_stale => true, :order
=> :created_at, :sort_mode
=> :desc, :with=>{:search_access_tag=>access_tags}
This seems to disables the access filtering and all projects are
returned - I would have expected no projects to be returned.
2. access_tags = ["CJNFDHJH"] # Random nonsense to try to get 0
returns
@search_results = ThinkingSphinx.search params[:search], :page =>
params[:page], :retry_stale => true, :order
=> :created_at, :sort_mode
=> :desc, :with=>{:search_access_tag=>access_tags}
This returns 5 projects all from the same project type. I've checked
and there seems to be nothing special about this one project type.
I would have thought that has and with on a string would be an exact
string match so if the string is not found in the :with array it would
not return any results.
>From the ts generated config, here are the bits related to
search_access_tag:
sql_query = .... IFNULL(`projects`.`search_access_tag`, '') AS
`search_access_tag` ....
sql_attr_str2ordinal = search_access_tag
Any ideas?
Warm regards,
Robert
On Jun 29, 8:38 am, rbjarnason <[email protected]> wrote:
> Hi Pat,
>
> Thanks for a quick answer :)
>
> Couple of follow up points.
>
> With a theoretical limit of about 2500 users and few hundred
> projects. Would the former approach be possible/practical/workable?
>
> Reason I'm asking is that we're being asked if it would be possible to
> add another layer of access control where each project would both have
> a project type and a client id and the ProjectAccess would then have
> (project_type_id, client_id, user_id).
>
> I guess it would be simpler to collect the user_ids in the index for
> each project with that extra access dimension.
>
> Our access filter would look something like this:
> named_scope :filtered, lambda {{ :joins=>"INNER JOIN project_access
> ON project_access.project_type_id = projects.project_type_id AND \
>
> project_access.client_id = projects.client_id",
> :conditions =>
> ["project_access.user_id = ?", Thread.current[:user_id]] }}
>
> I noticed that you've recently added a :join option to the code, which
> I gathered could be used in this case to collect the ids for the
> index, do you have any example snippets for using this feature?
>
> Or would it be possible somehow to combine the project_type_id and
> client_id in the second approach and search :with a combination of the
> two?
>
> Warm regards,
> Robert
>
> On Jun 29, 4:44 am, Pat Allan <[email protected]> wrote:
>
>
>
> > Hi Robert
>
> > I guess there's two approaches here... you'll either want to store all the
> > user ids that have access to a given project:
>
> > has project_type.project_accesses.user_id, :as => :user_ids
>
> > However, if you're going to have a lot of users, this may not be the best
> > approach... I would recommend you store the project type id as an attribute
> > instead:
>
> > has project_type_id
>
> > Then, find out which project types a user has access to:
>
> > project_type_ids = ProjectAccess.find(:all, :conditions => {:user_id =>
> > current_user.id}).collect { |access| access.project_type_id }
>
> > And use that as a filter in the search:
>
> > Project.search 'foo', :with => {:project_type_id => project_type_ids}
>
> > Hope this helps.
>
> > --
> > Pat
>
> > On 29/06/2010, at 11:55 AM, rbjarnason wrote:
>
> > > Hi,
>
> > > I'm trying to implement search using Thinking Sphinx for Projects that
> > > have access control based on Project Types.
>
> > > I have 4 tables I need to work with:
> > > * Project (included in search)
> > > * Project Type (included by association in search)
> > > * User (the logged in user)
> > > * Project Access (which has project_type_id, user_id)
>
> > > When logged in, I would only like to return search results for
> > > projects of types that a given user has access to as defined in the
> > > Project Access table.
>
> > > I've been looking at this post: "Limiting search results depending on
> > > authorization level" that has given me few clues but I'm still at a
> > > loss how I begin implementing this sort of access control using
> > > Thinking Sphinx.
> > >http://groups.google.com/group/thinking-sphinx/browse_thread/thread/4...
>
> > > Any leads would be highly appreciated.
>
> > > Warm regards,
> > > Robert Bjarnason
>
> > > --
> > > You received this message because you are subscribed to the Google Groups
> > > "Thinking Sphinx" group.
> > > To post to this group, send email to [email protected].
> > > To unsubscribe from this group, send email to
> > > [email protected].
> > > For more options, visit this group
> > > athttp://groups.google.com/group/thinking-sphinx?hl=en.
--
You received this message because you are subscribed to the Google Groups
"Thinking Sphinx" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/thinking-sphinx?hl=en.