Tag video, useful
Click on tag to remove it from topic's filter
posted 9 months ago (13 March 2008 at 8:11)
As this is the first topic in this section, i would like to explain what it about. While developing Forulio we solve some issues. Hope that our solutions can help someone too. Actually, all the code is going to be public after our first release, but anyway it is better to read article then code

So first issue is how to show for each user which topic was read by him and which is not. First, I created new model that will store last_read_post_id for each user and for each topic:

class ReadTopic < ActiveRecord::Base
belongs_to :user
belongs_to :topic
end

Then every time user open topic, let's save this action to ReadTopic, method is in User model:

def read_topic(topic)
read_topic = ReadTopic.find(:first, :conditions=>["user_id=? and topic_id=?", self.id, topic.id])
if read_topic
read_topic.update_attributes({:last_read_post=>topic.last_post})
else
ReadTopic.create(:user=>self, :topic=>topic, :last_read_post_id=>topic.last_post_id)
end
end

In appropriate view add this line:
<%current_user.read_topic(@topic) unless current_user.nil?%>


Now let's show topics in specific forum. Every unread topic can be checked be method in Topic model:

def new?
return self.last_read_post.to_i!=self.last_post_id if self.respond_to? :last_read_post
end

Last thing is to add last_read_post property to Topic model that should be user specific. To do this we do special find if controller:

def show
@forum = Forum.find_by_id(params[:id])
joins = "as t"
select = "t.*"
if current_user
joins = " as t left join read_topics rp on rp.topic_id = t.id and rp.user_id=#{current_user.id}"
select = "t.*, rp.last_read_post_id as last_read_post"
end
conditions=["t.forum_id=?", @forum.id]
@topics = Topic.paginate :select=>select, :conditions=>conditions, :page => params[:page], :joins=>joins, :order => 'created_at DESC'
end


The last thing is that last_read_post property in Topic model is dynamic and user specific. There is no field with this name in topics table. To define this attribute in Topic model:

attr_protected :last_read_post


That is all.