Forum: Ruby on Rails acts_as_queue

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Carmen -. (Guest)
on 2006-05-31 02:24
wondering if anyone tried this patch. (i havent, seeing as its 1228
lines long, 10 months old, and cant take serious a patch many orders
larger than competing web frameworks)

in many cases i want to keep about 10 things around, eg recent searches,
new items (spanning multiple classes), referers, page views, without
logging them for perpetuity. so i guess this isnt a normal queue, more
like a pipe with a burning substance at one end..

my initial thoughts are 1) disable id auto-incremenet, find the oldest
record out of 10, and overwrite that with the newest (doing this via
normal model callbacks). or 2) use acts_as_list, and reorder all the
records whenever one is added (acts_as_nested_set seems to do this, but
it seems like a bit of a kludge). any other obvious and simple
solutions?
Tom M. (Guest)
on 2006-05-31 07:26
(Received via mailing list)
How about storing an array in session and keeping it trimmed?

--
-- Tom M.
Michael D. (Guest)
on 2006-05-31 09:45
(Received via mailing list)
> my initial thoughts are 1) disable id auto-incremenet, find the oldest
> record out of 10, and overwrite that with the newest (doing this via
> normal model callbacks). or 2) use acts_as_list, and reorder all the
> records whenever one is added (acts_as_nested_set seems to do this,
> but
> it seems like a bit of a kludge). any other obvious and simple
> solutions?

Is this per-user? It seems like it'd be nice to say:

   some_user.recent_searches.create_in_queue(:query => "Mishaps")

I actually don't know how to disable auto-incrementing off the top of
my head, and isn't that database-dependent? Maybe you could say:

   create_table :recent_searches, :id => false do |t|
     t.column :user_id, :integer
     t.column :position, :integer
     t.column :query, :string
   end

And then have a has_many :recent_searches with an extension on that
which deletes extras, puts the new recent_search before everything,
and then increments everything's position by 1:

   class User < ActiveRecord::Base

     has_many :recent_searches, :order => 'position asc' do
       def create_in_queue(options, limit = 10)
         @reflection.klass.delete_all("position >= #{limit} and (#
{@finder_sql})") if self.count > limit - 1
         search = create(options.update({:position => 0}))
         @reflection.klass.update_all("position = (position + 1)",
@finder_sql)
         self.reload
         search
       end
     end

   end

This reaches into the association's internals a bit. Maybe there is a
better way?

And if it's not per-user, the same sort of thing (without that
user_id field):

   class PageView < ActiveRecord::Base

     def self.create_in_queue(options, limit = 10)
       self.delete_all("position >= #{limit}") if self.count > limit - 1
       view = self.create(options.update({:position => 0}))
       self.update_all("position = (position + 1)")
       view
     end

   end

You can say PageView.create_in_queue(), but stuff like PageView.first
and PageView.each would also be nice...

I have tests for these if you want. (Using sqlite3.) I guess these
could be made into a plugin.


--
Michael D.
http://www.mdaines.com
This topic is locked and can not be replied to.