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