Acts_as_queue


#1

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?


#2

How about storing an array in session and keeping it trimmed?


– Tom M.


#3

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