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.
