Hello everyone :) This is my first post to this list so let me briefly introduce myself. I am a student at Imperial College London and am currently learning to ride the rails. Together with two other students I am developing a revolutionary job platform for students. At the moment I am implementing tagging into our application using DHH''s acts_as_taggable plugin. In my database I have a table with job listings. Every job listing has various tags. As intended by the acts_as_taggable plugin these tags are stored in a table called tags and linked to the job listings through a table called taggings. I also have a tag cloud showing the most popular tags. So far everything is working fine. Now I would like to modify my tag cloud in the following way: I have a page where users can narrow the job listings down using tags. They can click on a tag and then a list of all jobs carrying that tag is displayed. Now I would like to adjust my tag cloud accordingly. The tag cloud should now only show tags associated to the remaining jobs. In other words: By showing only those listings with a particular tag I am defining a subset of my database. Now I would like to show only tags out of that subset in my tag cloud. An example can be seen on http://www.extate.com/search.php?q=kensington . When you click on a tag the tags list gets updated and you can narrow your search down again using the new list of tags. Any ideas about how I could accomplish such a dynamic tag cloud? Please be as specific as possible as I am relatively new to Ruby and Rails. So far, my tag cloud is generated as described on http://www.juixe.com/techknow/index.php/2006/07/15/acts-as-taggable-tag-cloud/ Many thanks for your help, Aeneas --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Anyone? Could you at least point me in the right direction? Aeneas --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Sure, that''s pretty easy. You''ll need to extend the
acts_as_taggable plugin
though.
Lets say we add something like this to tab.rb:
def self.get_all_tagged_with_for_type(type, tags)
query = "SELECT taggable_id, name FROM"
query << " taggings, tags WHERE"
query << " tags.id = taggings.tag_id"
query << " AND name IN
(''#{sanitize(tags.join(''\'',\''''))}'')
AND
taggable_type = ''#{type.name}'';
end
That will return all object IDs of the given type for the given array of
tags.
so you might call it like this:
Tag.get_all_tagged_with_for_type(Job,
Tag.parse(params[:tags].tr('','', '' '')))
This assumes your URL looks something like:
www.site.com/?tags=tag1,tag2,tag3,tag4
You need to perform some better parsing if you want tags with spaces in
them. Tag.parse() will handle such tags if they''re quoted.
I''ve not tested any of this code, so no doubt it doesn''t work
without a
little work. But please note the use of sanitize() in the model method!
We''re taking user input and using it a query so we need to protected
against
SQL injection attacks
The annoying part comes when extending the existing plugin tab.rb.
Currently, Rails will reload the plugin in development for each request and
you''ll loose any methods you dynamically extended it with during
startup. So
for now stick the method inside the plugin and keep and eye out for Rails
1.2:
http://rails.techno-weenie.net/tip/2006/9/8/reloading-dynamically-extended-classes
Hope that helps
Ian
On 12/09/06, Aeneas
<aeneas.wiener-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:>
>
> Anyone? Could you at least point me in the right direction?
>
> Aeneas
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Oops, and of course we need to Tag.find_by_sql(query) in that model method ;) On 12/09/06, Ian Leitch <port001-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > Sure, that''s pretty easy. You''ll need to extend the acts_as_taggable > plugin though. > > Lets say we add something like this to tab.rb: > > def self.get_all_tagged_with_for_type(type, tags) > > query = "SELECT taggable_id, name FROM" > query << " taggings, tags WHERE" > query << " tags.id = taggings.tag_id" > query << " AND name IN (''#{sanitize(tags.join(''\'',\''''))}'') AND > taggable_type = ''#{ type.name}''; > > end > > That will return all object IDs of the given type for the given array of > tags. > > so you might call it like this: > > Tag.get_all_tagged_with_for_type(Job, Tag.parse(params[:tags].tr('','', '' > ''))) > > This assumes your URL looks something like: > www.site.com/?tags=tag1,tag2,tag3,tag4 > > You need to perform some better parsing if you want tags with spaces in > them. Tag.parse() will handle such tags if they''re quoted. > > I''ve not tested any of this code, so no doubt it doesn''t work without a > little work. But please note the use of sanitize() in the model method! > We''re taking user input and using it a query so we need to protected against > SQL injection attacks > > The annoying part comes when extending the existing plugin tab.rb. > Currently, Rails will reload the plugin in development for each request and > you''ll loose any methods you dynamically extended it with during startup. So > for now stick the method inside the plugin and keep and eye out for Rails > 1.2: > http://rails.techno-weenie.net/tip/2006/9/8/reloading-dynamically-extended-classes > > Hope that helps > Ian > > > On 12/09/06, Aeneas <aeneas.wiener-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > > Anyone? Could you at least point me in the right direction? > > > > Aeneas > > > > > > > > > > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk -~----------~----~----~----~------~----~------~--~---
Ian, many thanks for your reply!
It is still not doing what I want.
I simplified (for testing) the relevant part of the SQL query slightly
by adding the common tag manually:
query << " AND name IN (''hard'')"
Here is what I expected:
I wanted to see all tags assigned to those jobs which have also been
tagged with "hard".
However, that''s not what I am getting with this query. Instead I just
get the tag hard itself and nothing else. I am pretty sure everything
else is set up correctly. When I leave the line quoted above out then I
get all tags in the tags table so this is working.
Any suggestions?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
You need to iterate over the results and load each job using the taggable_id
value:
tagged_with = Tag.get_all_tagged_with_for_type(Job, [''hard''])
for tagged in tagged_with
job = Job.find(tagged[:taggable_id])
job.tag_list
end
You could move the query into a method inside your Job model and join on the
taggable_id and job id to save you having to iterate the results in this
way.
On 12/09/06, Aeneas
<aeneas.wiener-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:>
>
> Ian, many thanks for your reply!
> It is still not doing what I want.
> I simplified (for testing) the relevant part of the SQL query slightly
> by adding the common tag manually:
>
> query << " AND name IN (''hard'')"
>
> Here is what I expected:
>
> I wanted to see all tags assigned to those jobs which have also been
> tagged with "hard".
>
> However, that''s not what I am getting with this query. Instead I
just
> get the tag hard itself and nothing else. I am pretty sure everything
> else is set up correctly. When I leave the line quoted above out then I
> get all tags in the tags table so this is working.
>
> Any suggestions?
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Many thanks for your help!
I have now managed to output the correct tags to the browser as a comma
separated list.
Controller:
@jobs_tagged_with = Tag.find_by_name(params[:common_tag], :limit => 10
).tagged
View:
<% for job in @jobs_tagged_with %>
<%= job.tags.collect{|tag| tag.name}.join(", ") + ","
%>
<% end %>
However, that''s not quite what I want. How can I get the tags
currently displayed on screen in an array? This array could then be
used to feed my tag cloud.
I am sure this is nothing very difficult for someone a bit more
experienced with Ruby than I am. I am still trying to get my head
around all this...
Aeneas
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Displayed on the screen as an array object? or you want to convert a string
list of tags into an array? Not quite sure what you want.
If you meaning parsing the tags:
Tag.parse("tag1 tag2 \"tag3 with spaces\"") # Parse space
seperate list of
tags
=> ["tag3 with space", "tag1", "tag2"]
"tag1, tag2, tag3 with spaces".split('', '')
=> ["tag1", "tag2", "tag3 with spaces"]
If you mean an array as in something you can pass as a parameter in the URL,
then just use a comma seperated list and parse it in the receiving
controller.
On 13/09/06, Aeneas
<aeneas.wiener-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
wrote:>
>
> Many thanks for your help!
>
> I have now managed to output the correct tags to the browser as a comma
> separated list.
>
> Controller:
> @jobs_tagged_with = Tag.find_by_name(params[:common_tag], :limit => 10
> ).tagged
>
> View:
> <% for job in @jobs_tagged_with %>
> <%= job.tags.collect{|tag| tag.name}.join(", ") +
"," %>
> <% end %>
>
> However, that''s not quite what I want. How can I get the tags
> currently displayed on screen in an array? This array could then be
> used to feed my tag cloud.
>
> I am sure this is nothing very difficult for someone a bit more
> experienced with Ruby than I am. I am still trying to get my head
> around all this...
>
> Aeneas
>
>
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---
Finally, I have been able to figure out an SQL query which does all the
work for me. Here it is:
SELECT tags.name, count(*) AS count FROM jobs
JOIN taggings ON jobs.id = taggings.taggable_id
JOIN tags ON taggings.tag_id = tags.id
WHERE jobs.id IN ( SELECT jobs.id FROM jobs
JOIN taggings ON jobs.id = taggings.taggable_id
JOIN tags ON taggings.tag_id = tags.id
WHERE tags.name IN ("tag2", "tag3")
)
AND tags.name NOT IN ("tag2", "tag3")
GROUP BY tags.name
ORDER BY count DESC , tags.name
Aeneas
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk
-~----------~----~----~----~------~----~------~--~---