# Implementing a user activity log with STI. (?)

**URL:** <https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675>\
**Category:** Rails\
**Created:** [August 13, 2009, 6:14am UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675 "2009-08-13T06:14:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [August 13, 2009, 6:14am UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675/1 "2009-08-13T06:14:42Z")

</div>

Can anyone tell me if I’m on the right track? I think this isn’t  
quite right:

I want to implement an activity log for users. It’ll show them a list  
of the objects they’ve viewed. I have, of course, many types of  
objects in the Rails program.

I’ve thought that I’d make a log\_entries table which would have  
a :viewed\_object\_id and :viewed\_object\_type.

I’d then like to be able to retrieve all of the viewed objects,  
something along the lines:

user.log\_entries.map{|e| e.viewed\_object}

And I could display links to them, like:

link\_to obj.to\_s, obj

…so, this is a form of STI, but I’m not sure if Rails handles this  
kind. I’m also not sure if this is the best way to implement this  
kind of feature.

Thanks for any feedback!

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [August 13, 2009, 6:30am UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675/2 "2009-08-13T06:30:31Z")

</div>

Hi Robb,

I ended up writing a very crude solution and then stopped that to  
revamp later. I DO believe you are on the right track though. The only  
part that I havent figured out though is writing neat code for the  
actual message or sentence the user will read. Like,

You edited the task - Change tyres on car  
Robb completed the task - Change tyres on car

These sentences will vary depending on the action, object and user. To  
generate them using a function is, at least in my case, not possible.  
Im hard coding them right now.

Read up on polymorphic relationships. Its basically what you have  
suggested above, only, Rails makes it a bit easier.

> **[ActiveRecord::Associations::ClassMethods](https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html)**
>
> Associations are a set of macro-like class methods for tying objects together through foreign keys.

Good luck!  
And DO update this post with your efforts.

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [August 13, 2009, 7:50am UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675/3 "2009-08-13T07:50:43Z")

</div>

Thanks, Ram. Yep, I realized that polymorphic associations is exactly  
what I was talking about. In my case, all the log info is private and  
per-user. Also, the only action is “view”, so I have a simpler case  
than you. I just need to generate a list like,

Today  
Document 452.242  
Document 551.432

Yesterday  
Document 43.234  
Chapter 452

Now, in your case, I wouldn’t worry at _all_ about how to generate the  
text. This is an issue for the presentation layer. I’d just be  
concerned with making sure I have all the relevant objects so that the  
various templates can render the output appropriately: the currently  
logged in user, a list of log entries, each of which has a reference  
to the relevant object, the method invoked, and the user who did it.

I suggest checking out the “Command” design pattern. It kind of  
sounds like what you’re doing.

- Robb

On Aug 12, 9:29 pm, Ram [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> … The only  
> part that I havent figured out though is writing neat code for the  
> actual message or sentence the user will read. Like,

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [August 13, 2009, 8:27am UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675/4 "2009-08-13T08:27:35Z")

</div>

Nice. Went through a wiki article on Command Pattern. Very much the  
design i need. Will try to do that when I get back to the activity  
log :).  
Thanks.

---

<div class="post-metadata">

**Author:** ![robb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a183cd/32.png) [@robb](https://www.ruby-forum.com/u/robb)\
**Post date:** [October 5, 2009, 3:51pm UTC](https://www.ruby-forum.com/t/implementing-a-user-activity-log-with-sti/173675/5 "2009-10-05T15:51:20Z")

</div>

Hi,  
you guyes are doing what I want to implement soon. So I had some  
thoughts about an activity log. Pretty sure polymorphic associations  
are a good choice. To keep the rest clean from logging code and the  
logging flexible, I thought about using an observer, like

class ActivityObserver \< ActiveRecord::Observer  
observe :model\_2\_observe\_01, model\_2\_observe\_2 #, …

def after\_save(record)  
activity = Activity.new(record)  
activity.save  
end  
end

Should do it. I just wonder if Rails ensures ACID behavoir for  
observers, anyone knows?

Cheers,  
Chris
