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. -- Posted via http://www.ruby-forum.com/.
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? -- Posted via http://www.ruby-forum.com/.
This is the same problem I am experiencing, but have not had time to investigate it yet. I believe it is a bug. Britt On 11/28/06, Matthew Planchant <matt at planchant.co.uk> wrote:> 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? > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Ferret-talk mailing list > Ferret-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/ferret-talk >
>> 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. -- Posted via http://www.ruby-forum.com/.
> 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. -- Posted via http://www.ruby-forum.com/.
Hi! please see comments below. On Tue, Nov 28, 2006 at 04:18:44PM +0100, Matthew Planchant wrote:> > > 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 = @topicsactually 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 kraemer at webit.de Schnorrstra?e 76 Tel +49 351 46766 0 D-01069 Dresden Fax +49 351 46766 66
Jens Kraemer 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? -- Posted via http://www.ruby-forum.com/.
On Tue, Nov 28, 2006 at 05:29:23PM +0100, Matthew Planchant wrote:> Jens Kraemer 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 ;-) cheers, Jens -- webit! Gesellschaft f?r neue Medien mbH www.webit.de Dipl.-Wirtschaftsingenieur Jens Kr?mer kraemer at webit.de Schnorrstra?e 76 Tel +49 351 46766 0 D-01069 Dresden Fax +49 351 46766 66
> I already answered these in my last mail, but seems you snipped a bit > too much away ;-)Thanks :D -- Posted via http://www.ruby-forum.com/.
Jens Kraemer 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 = -- Posted via http://www.ruby-forum.com/.
>> has_many :documents, :through => :document_topics >> @document.topic_ids = @topics > actually I wonder if this works at allForgot to mention that topic_ids is defined elsewhere. -- Posted via http://www.ruby-forum.com/.
> undefined method `disable_ferret'' for nil:NilClassAnyone know what I should do about this? -- Posted via http://www.ruby-forum.com/.
On Tue, Nov 28, 2006 at 05:47:47PM +0100, Matthew Planchant wrote:> Jens Kraemer wrote: > > @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 > =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 kraemer at webit.de 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 -- Posted via http://www.ruby-forum.com/.
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 :-)> 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 >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 > endyou 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 kraemer at webit.de 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]) ? -- Posted via http://www.ruby-forum.com/.
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 ;-) cheers, Jens On Thu, Nov 30, 2006 at 06:21:12PM +0100, Jens Kraemer wrote:> 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 :-) > > > 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 > > > > 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 kraemer at webit.de > Schnorrstra?e 76 Tel +49 351 46766 0 > D-01069 Dresden Fax +49 351 46766 66 > _______________________________________________ > Ferret-talk mailing list > Ferret-talk at rubyforge.org > http://rubyforge.org/mailman/listinfo/ferret-talk >-- webit! Gesellschaft f?r neue Medien mbH www.webit.de Dipl.-Wirtschaftsingenieur Jens Kr?mer kraemer at webit.de Schnorrstra?e 76 Tel +49 351 46766 0 D-01069 Dresden Fax +49 351 46766 66
On Thu, Nov 30, 2006 at 06:35:54PM +0100, Matthew Planchant wrote:> > > 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])nearly ;-) @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 kraemer at webit.de Schnorrstra?e 76 Tel +49 351 46766 0 D-01069 Dresden Fax +49 351 46766 66