AAF: merge search results


#1

Hi,
I have a user model that has a couple of other models(like street
address, tasks).

suppose
User has a name field
Address has a state field.

so I want to provide a detailed search form each field in the user and
its related
models can be specified.

Suppose I have a user that has a name “california”, and that user has a
address with the state field being “california” as well.

I use AAF’s multi_search:

User.multi_search(‘state:(california)’, [Address, Task])
returns the correct address instance

User.multi_search('name:(california) ', [Address, Task])
returns the correct user instance

User.multi_search('name|state:(california) ', [Address, Task])
return both the address and user instances where the address actually
belongs to the user that’s returned. how can I just get one result
returned? Otherwise, I’d need to merge these two results because they
really represent the same user. I understand that I can define a new
method to return the state in the user model. But I have many other
models that belong to a user. so it’s going to be very tedious to add
all the new accessor methods just for AAF.

User.multi_search('name:(california) state:(california) ', [Address,
Task])
doesn’t return any instance. why is this not returning anything?

Thanks.
yaxm


#2

Hi!

please see comments below.

On Mon, Apr 16, 2007 at 11:48:33AM +0200, Yaxm Y. wrote:

models can be specified.

all the new accessor methods just for AAF.
Ferret has no way to specify or handle such relationships between
records. So if you always only want to find user instances in the end,
the logical decision would be to only index users, adding in the data
from other related objects like addresses and so on as needed.

As we’re doing Ruby here, I’m sure there is a non-tedious way to
construct the accessor methods for the related record data :wink:

If you don’t like that, what about indexing the user_id along with each
Address and Task?
Then you could run your search and just retrieve the user_ids directly
from the index by using the :lazy option:

result = User.multi_search('name|state:(california) ', [Address, Task],
:lazy => [:user_id])

Now collect the user_ids from these results (due to the lazy option no
db calls will be made for this, just be sure to give the :store => :yes
option for the :user_id field).

User.multi_search('name:(california) state:(california) ', [Address,
Task])
doesn’t return any instance. why is this not returning anything?

because AAF uses an implicit AND between query terms - so this query is
looking for a record having both name:california and state:california.

multi_search('name:(california) OR state:(california) ', [Address,
Task])

should find both records.

Jens


Jens Krämer
webit! Gesellschaft für neue Medien mbH
Schnorrstraße 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
removed_email_address@domain.invalid | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa


#3

Jens,
can you tell me what’s wrong with my attemp to define accessors in a
not-so-tedious way?

With my Task active record model, I try to define accessors for
first_name and last_name:

def Task.my_new_accessors(object, attributes)
attributes.each do |v|
define_method( v.to_sym ) do
(object).send v.to_s
end
end
end

my_new_accessors :user, [ :last_name, :first_name]

But I got the following errors:

Task.new.last_name
NoMethodError: undefined method `last_name’ for :user:Symbol

Thanks.


#4

On Mon, Apr 23, 2007 at 04:21:24AM +0200, Yaxm Y. wrote:

      (object).send v.to_s

as the error tells you, you call last_name on the Symbol :user here.
self.send(object).send(v)
should work (not tested, though).

Jens


Jens Krämer
webit! Gesellschaft für neue Medien mbH
Schnorrstraße 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
removed_email_address@domain.invalid | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa


#5

Jens,
that works!

I created this module and put that in a ruby file in the lib folder
under my rails app,

module MyModule
module Accessor
module ClassMethods
def mm_proxy_accessor(object, attributes)
attributes.each do |v|
define_method( v.to_sym ) do
obj = self.send(object)
if(obj.nil?)
return nil
else
obj.send v.to_s
end
end
end
end
end

def self.included(base)
  base.extend(ClassMethods)
end

end
end

Then I include it in my User model.

but Ruby complains with this error:
NameError: uninitialized constant User::MyModule

if I put the module definition in my User.rb file, it works fine.

what am I doing wrong?

Thanks.
Yaxm


#6

On Sat, Apr 28, 2007 at 10:57:28AM +0200, Yaxm Y. wrote:

    attributes.each do |v|
end

NameError: uninitialized constant User::MyModule
try name that file my_module.rb so Rails has a chance to find it when
you use the module. Or require the file in environment.rb.

Jens


Jens Krämer
webit! Gesellschaft für neue Medien mbH
Schnorrstraße 76 | 01069 Dresden
Telefon +49 351 46766-0 | Telefax +49 351 46766-66
removed_email_address@domain.invalid | www.webit.de

Amtsgericht Dresden | HRB 15422
GF Sven Haubold, Hagen Malessa