Index not being updated

My index is not being updated when I add new records or amend existing
ones.

Can anyone point me in the direction of where I should be looking for
what is going wrong?

I’m running this in the production environment.

Matthew Planchant wrote:

My index is not being updated when I add new records or amend existing
ones.

Can anyone point me in the direction of where I should be looking for
what is going wrong?

I’m running this in the production environment.

Is an amended record added to the index when .save is called?

My index is not being updated when I add new records or amend existing
ones.

Can anyone point me in the direction of where I should be looking for
what is going wrong?

I’m running this in the production environment.

Is an amended record added to the index when .save is called?

Looks as though attributes from many to many relationships are not being
added to the index when a record is amended.

This is the same problem I am experiencing, but have not had time to
investigate it yet. I believe it is a bug.

Britt

Looks as though attributes from many to many relationships are not being
added to the index when a record is amended.

I have the following relationship between documents and topics:

class Document < ActiveRecord::Base
acts_as_ferret :additional_fields => [:topic_titles]

has_many :document_topics, :dependent => true
has_many :topics, :through => :document_topics

def topic_titles
topics.collect { |topic| topic.title }.join ’ ’
end
end

class Topic < ActiveRecord::Base
has_many :document_topics, :dependent => true
has_many :documents, :through => :document_topics
end

The update action in documents_controller.rb looks like this:

def update
params[:document][:topic_ids] ||= []
@document = Document.find(params[:id])
@topics = (params[:topics] or []).collect { |item| item.to_i }
@document.attributes = params[:document]
@document.topic_ids = @topics
@document.save

if @document.update_attributes(params[:document])
  flash[:notice] = 'Document was successfully updated.'
  redirect_to :action => 'show', :id => @document
else
  render :action => 'edit'
end

end

I suspect there is something here which means the document has no topics
when acts_as_ferret attempts to add the topic_titles to the index.

Hi!

please see comments below.

On Tue, Nov 28, 2006 at 04:18:44PM +0100, Matthew Planchant wrote:

has_many :documents, :through => :document_topics
@document.topic_ids = @topics
actually I wonder if this works at all - I’d be surprised if you can
assign ids to a has_many :through relationship like that. However
you could try this:

  @document.disable_ferret
  if @document.update_attributes(params[:document])
    @document.ferret_update
    flash[:notice] = 'Document was successfully updated.'
    redirect_to :action => 'show', :id => @document
  else
    render :action => 'edit'
  end
end

I suspect there is something here which means the document has no topics
when acts_as_ferret attempts to add the topic_titles to the index.

the problem with indexing data from related objects seems to be that the
after_update hook of aaf is called too early, that is, before all
relationships are saved. Most often it helps to first save the record
(and skip the indexing, which saves some time) and index the record
after that.

cheers,
Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

On Tue, Nov 28, 2006 at 05:29:23PM +0100, Matthew Planchant wrote:

How do I do this? Can I explicitly stop the indexing beginning then
start it when I have completed saving the record?

I already answered these in my last mail, but seems you snipped a bit
too much away :wink:

cheers,
Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

Jens K. wrote:

the problem with indexing data from related objects seems to be that the
after_update hook of aaf is called too early, that is, before all
relationships are saved.

Yes. This is what I thought might be going on.

Most often it helps to first save the record and skip the indexing,
(which saves some time) and index the record after that.

How do I do this? Can I explicitly stop the indexing beginning then
start it when I have completed saving the record?

I already answered these in my last mail, but seems you snipped a bit
too much away :wink:

Thanks :smiley:

Jens K. wrote:

has_many :documents, :through => :document_topics
@document.topic_ids = @topics
actually I wonder if this works at all - I’d be surprised if you can
assign ids to a has_many :through relationship like that.

Yep. It works.

However you could try this:

  @document.disable_ferret
  if @document.update_attributes(params[:document])
    @document.ferret_update
    flash[:notice] = 'Document was successfully updated.'
    redirect_to :action => 'show', :id => @document
  else
    render :action => 'edit'
  end
end

I get the error below. Do I need to include anything at the top of my
controller for this to work?

==
undefined method `disable_ferret’ for nil:NilClass

has_many :documents, :through => :document_topics
@document.topic_ids = @topics
actually I wonder if this works at all

Forgot to mention that topic_ids is defined elsewhere.

undefined method `disable_ferret’ for nil:NilClass

Anyone know what I should do about this?

On Tue, Nov 28, 2006 at 05:47:47PM +0100, Matthew Planchant wrote:

I get the error below. Do I need to include anything at the top of my
controller for this to work?

==
undefined method `disable_ferret’ for nil:NilClass

that error means that @document (the object you call disable_ferret on)
is nil.

Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

I got this working by disabling ferret for a block like this:

def update
params[:document][:topic_ids] ||= []
@document = Document.find(params[:id])

@document.disable_ferret do
  @topics = (params[:topics] or []).collect { |item| item.to_i }
  @document.attributes = params[:document]
  @document.topic_ids = @topics
  @document.save
end

if @document.update_attributes(params[:document])
  flash[:notice] = 'Document was successfully updated.'
  redirect_to :action => 'show', :id => @document
else
  render :action => 'edit'
end

end

On Thu, Nov 30, 2006 at 06:00:58PM +0100, Matthew Planchant wrote:

I got this working by disabling ferret for a block like this:

glad to hear :slight_smile:

imho it would be better to not call update_attributes in this place, as
you already saved the document inside the block above. It’s one line
more for the explicit call to ferret_update but should save you one
update call to your DB.

so instead of this:

if @document.update_attributes(params[:document])

this should work, too:

  if @document.valid?
    @document.ferret_update
  flash[:notice] = 'Document was successfully updated.'
  redirect_to :action => 'show', :id => @document
else
  render :action => 'edit'
end

end

you could even store the return value from the save call inside the
block and use that in the if statement…

Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

imho it would be better to not call update_attributes in this place, as
you already saved the document inside the block above. It’s one line
more for the explicit call to ferret_update but should save you one
update call to your DB.

so instead of this:

if @document.update_attributes(params[:document])

this should work, too:

  if @document.valid?
    @document.ferret_update
  flash[:notice] = 'Document was successfully updated.'
  redirect_to :action => 'show', :id => @document
else
  render :action => 'edit'
end

end

you could even store the return value from the save call inside the
block and use that in the if statement…

Thanks for the reply Jens.

Is this because:

@document.attributes = params[:document]

does the same as:

@document.update_attributes(params[:document])

?

On Thu, Nov 30, 2006 at 06:35:54PM +0100, Matthew Planchant wrote:

block and use that in the if statement…

Thanks for the reply Jens.

Is this because:

@document.attributes = params[:document]

does the same as:

@document.update_attributes(params[:document])

nearly :wink:

@document.attributes = params[:document]
@document.save

does the same as

@document.update_attributes(params[:document])

Jens


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66

Update: As it turned out I have a very similar situation in some
controller I’m just writing, so I just committed a small tweak to
make it less noisy:

def update
params[:document][:topic_ids] ||= []
@document = Document.find(params[:id])

 # this will call ferret_update after the block, if the block evals
 # to true (which is the case when save succeeds). as a bonus, it
 # also returns the value returned by the block so we can use it in
 # the if statement :-)
 if @document.disable_ferret(:index_when_true) {
      @topics = (params[:topics] or []).collect { |item| item.to_i }
      @document.attributes = params[:document]
      @document.topic_ids = @topics
      @document.save
    }
   flash[:notice] = 'Document was successfully updated.'
   redirect_to :action => 'show', :id => @document
 else
   render :action => 'edit'
 end

end

the method name ‘disable_ferret’ doesn’t fit this usage pattern that
nice, I’m open to suggstions :wink:

cheers,
Jens

On Thu, Nov 30, 2006 at 06:21:12PM +0100, Jens K. wrote:

  @topics = (params[:topics] or []).collect { |item| item.to_i }
  render :action => 'edit'

webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66


Ferret-talk mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ferret-talk


webit! Gesellschaft für neue Medien mbH www.webit.de
Dipl.-Wirtschaftsingenieur Jens Krämer [email protected]
Schnorrstraße 76 Tel +49 351 46766 0
D-01069 Dresden Fax +49 351 46766 66