Hi Pat,

Cool. Thanks for the filtering workaround, that works fine.

Warm regards,
Robert

On Jun 30, 2:53 am, Pat Allan <[email protected]> wrote:
> Hi Robert
>
> Good to see you spotted the docs on CRC'ing string attributes.
>
> Unfortunately, when you add a filter, it needs to apply to all indexes. As a 
> work-around, you could add an integer (or CRC'd string, if you really want) 
> as the attribute to all other indexed models - and then include that when 
> filtering:
>
>   has '0', :as => :search_access_tag, :type => :integer
>
>   ThinkingSphinx.search :with => {:search_access_tag => (access_tags.collect 
> { |tag| tag.to_crc32 } + 0)}
>
> I think that should work - the only problem is if any of your access tags are 
> blank (which I'm pretty sure is CRC'd to 0). Sphinx doesn't have the concept 
> of signed integers, though, so 0 or 1 or something small is best.
>
> Cheers
>
> --
> Pat
>
> On 30/06/2010, at 2:30 AM, rbjarnason wrote:
>
>
>
> > Hi,
>
> > Ok, didn't read enough of the manual...  It was due to not using
> > CRC32.  Seems to be working now except for passing an empty array to
> > the :with but I can work around that by using a random string that
> > will never be a real find.
>
> > One final question, when using ThinkingSphinx.search and :with can I
> > conditions the :with parameter only to apply to the Projects table?  I
> > have a couple of other tables that are searchable and they do not have
> > the search_access_tag field and they don't seem to showing up anymore.
>
> > Warm regards,
> > Robert
>
> > On Jun 29, 5:11 pm, rbjarnason <[email protected]> wrote:
> >> 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 
> > 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.

Reply via email to