# Displaying related entries by tags - HELP!

**URL:** <https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193>\
**Category:** Rails\
**Created:** [March 13, 2006, 4:50am UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193 "2006-03-13T04:50:37Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 13, 2006, 4:50am UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/1 "2006-03-13T04:50:37Z")

</div>

Ok, my site is setup like pretty much every other blog out there. A  
list of the most recent 5 posts, then by clicking one, you go to an  
individual post page, displaying the full context of that post.

Now, what I would like to do is to display the related entries in the  
side column, which is part of the layout, based on the tags belonging to  
that specific entry.

Here’s my coding so far:

#view  
\<% for post in @posts %\>

## \<%= post.title %\>

tags: \<%= post.tags.collect { |tag| link\_to tag.name, :controller =\>  
“articles”, :action =\> “by\_category”, :category =\> tag.name.to\_s  
}.join(", ") %\>

\<%= post.entry %\>

\<% end %\>

#layout  
\<% for related in @contents\_related %\>

- \<%= related.title %\>  
\<% end %\>

#controller (how do I pass the tag\_id and the content\_id?)  
@contents\_related = Content.show\_related\_entries(?,?)

#model  
def self.show\_related\_entries(t\_id, c\_id)  
find\_by\_sql(“select c.title from contents c inner join contents\_tags  
ct on c.id = ct.content\_id where ct.tag\_id = #{t\_id} and c.id !=  
#{c\_id}”)  
end

The function works if I manually pass a content\_id (for my entry) and a  
tag id (for a tag of that entry). Now, how can I dynamically pull out  
the single content\_id for the post, but execute the function for each  
tag related to that individual post???

Hopefully you can see what I’m trying to accomplish, and can have a  
suggestion (even if it’s completely different) as to how I can get this  
working!

Thanks for any help!

---

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 13, 2006, 10:26am UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/2 "2006-03-13T10:26:41Z")

</div>

Am Montag, den 13.03.2006, 04:50 +0100 schrieb ryan:

> #view
> 
> ```
> find_by_sql("select c.title from contents c inner join contents_tags 
> 
> ```
> 
> suggestion (even if it’s completely different) as to how I can get this  
> working!
> 
> Thanks for any help!

Hi Ryan,

your message is a little confusing, because of these mass of different  
names you use. Names you have in your code or talking about are: post,  
tag, entry, category, related, content, related\_content,  
related\_entries, contents\_tags

I am not sure what you title content and entry within a blog. What i  
would expect is post, comment, tag (or keyword). What are  
related\_contents and entries? Where is the difference between content  
and entry? Maybe you can do a little refactoring.

Please clarify this and try to describe your problem again. If i would  
understand it, i probably could help you.

## Ciao, Norman

Norman T.

[http://blog.inlet-media.de](http://blog.inlet-media.de)

---

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 13, 2006, 2:31pm UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/3 "2006-03-13T14:31:29Z")

</div>

Yes, I understand what you mean, it is confusing. Ok, basically, all I  
want to do is pull a list of related entries which will be displayed in  
the layout in a column to the right, but it must be based on the current  
entry loaded into the view.

I can write a sql query to accomplish this, but I don’t know how to get  
the id of the tag (and there will be multiple tags to check, so I need a  
loop?) as well as the id of the post (or entry).

The way I load my posts is with a for loop. So, in words, I do this in  
the view:

#view  
\<% for [variable\_name] in [@class\_variable\_holding\_the\_data] %\>  
\<% [variable\_name].title %\>

#get the tags  
\<% [table\_name].tags.collect {|tag| tag.name} %\>

\<% end %\>

Now, the @class\_variable\_holding\_the\_data, in this case, is one entry  
based on a permalink. I need to pass that ID along with some sort of  
loop to get all of the tag IDs, and display this in the layout.

I’m still probably confusing you really bad, but maybe you can now see  
what I’m trying to do. If not, it’s ok, i’m not very good with  
explaining stuff.

Basically, I want to pull related entries in the layout based on any  
number of tags for an individual entry loaded into the view. If you  
know a better way, I’m open for suggestions. Thanks!

---

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 13, 2006, 6:52pm UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/4 "2006-03-13T18:52:33Z")

</div>

Yes, that’s exactly what I’m trying to do, and I like your suggestions  
very much. That was my original intention, but lack of experience let  
me come up with it. Now, I’m trying to follow what you said to try, and  
I’m getting a “no method” error for ‘related\_entries’.

Is it possible to use the permalink to get the individual entry instead  
of the id? Like so:

EntriesController \< ApplicationController  
def show  
@entry = Entry.find\_by\_permalink(params[:permalink])  
@related\_entries = @entry.related\_entries  
end  
end

That’s what I’m trying. The method ‘related\_entries’ is defined in the  
Tag.rb file, is that what you intended?

You said to add a “find” method in my entry model, but then defined  
‘related\_entries’ in the tag model.

You obviously know what you’re talking about, but I’m new at all of  
this, so I’m still somewhat confused.

Any suggestions?

---

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 13, 2006, 3:57pm UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/5 "2006-03-13T15:57:39Z")

</div>

Am Montag, den 13.03.2006, 14:31 +0100 schrieb ryan:

> the view:  
> Now, the @class\_variable\_holding\_the\_data, in this case, is one entry  
> based on a permalink. I need to pass that ID along with some sort of  
> loop to get all of the tag IDs, and display this in the layout.
> 
> I’m still probably confusing you really bad, but maybe you can now see  
> what I’m trying to do. If not, it’s ok, i’m not very good with  
> explaining stuff.
> 
> Basically, I want to pull related entries in the layout based on any  
> number of tags for an individual entry loaded into the view. If you  
> know a better way, I’m open for suggestions. Thanks!

Ok, i try to replay this:

You have a many-to-many association Entry ↔ Tag.

Now you want to get all the entries, that share the same tags of a  
specific entry, right?

Add a find method to your entry model, that does the magic. Don’t do  
this in the view. Another place may be the controller, but for finders  
use the model.

class Tag \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :entries

def related\_entries  
tags.collect { |tag| tag.entries }.flatten.uniq  
end  
end

class Entry \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :tags  
end

Perhaps this solution might be a little bit slow, if you have a lot of  
data. Try using this find method:

class Tag \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :entries

def related\_entries  
tag\_ids = tags.collect { |tag| tag.id }  
Entries.find(  
:all,  
:include =\> tags,  
:conditions =\> [‘tag.id IN (?)’, tag\_ids.join(‘,’)]  
)  
end  
end

No matter what way you go, you don’t have to deal with ids:

# view

\<% for entry in @entries %\>  
\<% entry.title %\>

# get the related entries

\<% for related in entry.related\_entries %\>  
\<%= related.title %\>  
\<% end %\>  
\<% end %\>

The perfect way would be to preload the related entries in your  
controller and put them into an own instance variable, so if you need  
them twice in a view, they are only loaded once.

EntriesController \< ApplicationController  
def show  
@entry = Entry.find(params[:id])  
@related\_entries = @entry.related\_entries  
end  
end

This is the best way, if you want the related entries linked in a  
sidebar. In your sidebar view just test if the @related\_entries is not  
nil and then iterate over them and spit out links.

–  
Norman T.

[http://blog.inlet-media.de](http://blog.inlet-media.de)

---

<div class="post-metadata">

**Author:** ![ryan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a8b319/32.png) [@ryan](https://www.ruby-forum.com/u/ryan)\
**Post date:** [March 14, 2006, 9:11am UTC](https://www.ruby-forum.com/t/displaying-related-entries-by-tags-help/80193/6 "2006-03-14T09:11:05Z")

</div>

Am Montag, den 13.03.2006, 18:52 +0100 schrieb ryan:

> @entry = Entry.find\_by\_permalink(params[:permalink])  
> @related\_entries = @entry.related\_entries  
> end  
> end

Sure, the code above should work as expected.

> That’s what I’m trying. The method ‘related\_entries’ is defined in the  
> Tag.rb file, is that what you intended?

No, the related\_entries method should be defined in the Entry model, as  
it is finding Entry models. The method is finding related entries, that  
share the same tags as the entry, on wich you call the related\_entries  
method.

> You said to add a “find” method in my entry model, but then defined  
> ‘related\_entries’ in the tag model.

It is a find method without the find word in the method name 😉 Call it  
find\_related\_entries, if you like. It’s just a naming thing. Sorry for  
the confusion.

> You obviously know what you’re talking about, but I’m new at all of  
> this, so I’m still somewhat confused.

## Hope that helps.

Norman T.

[http://blog.inlet-media.de](http://blog.inlet-media.de)
