Rails Dynamic tag generation from context - ruby-on-rails

Let's say I want to trend all comments posted on a site and create dynamic tags. For example, If there are x number of comments that contain the word iPad I would like to create automatically create a tag called "iPad" and put it in a tag cloud.
Is this possible? I checked out the acts_as_taggable gem but it requires one to specify a tag, I guess I am looking for a way to generate tags from content.

Well something like the yahoo term extraction service might do the trick and there is a plugin for it http://expressica.com/auto_tags/.
Though it is not for commercial use.

Sure, this is possible.
Just parse the content of each comment as it's passed in and attach the tags you're interested in.
This can either work on a whitelist - where you specify all the tags you're interested in and attach those if relevant.
Or it could work on a blacklist - where you specify all the words to ignore, e.g. "the", "on". This approach is probably a lot more time consuming, but would allow for more dynamic results.
I would probably work on a white list, then have an ability to add new tags to the whitelist and have it go back and retroactively add the tags where applicable.

Related

How can I make a rails model searchable by the user?

I'm trying to expose a search feature in rails. I want a user to be able to enter a string like name:"john" color:"blue" and get a list of ActiveRecord objects for some model that have a name attribute containing john and a color attribute containing blue. I'd also like them to be able to use and and or and parentheses e.g. name:"john" or color:"blue" or (name:"john" color:"blue") or name:"bill". Ideally they could also use things like age<20 where age is an numeric field. Is there a rails plugin that does this. I've was looking briefly at sphinx and ferret both of which seem to create an api for this but it was unclear whether they provided a clear text based option or if I would need to parse the search strings myself.
Ernie's Ransack gem is a good place to start.
You will have to provide an intermediate layer between your submitted form and the Ransack code (this would be a good idea anyway for security reasons) to convert strings from the format you desire to something Ransack can understand.
If you check the demo page and the documentation for the gem you'll find it's quite simple to create the sort of queries you're after.
Watch how GET requests are generated from the conditions you build and in your application replace the builder Ernie has in the demo with a single textfield accepting strings like (name:"john" color:"blue") or name:"bill". Do some pattern matching when this field is submitted and build a proper querystring to pass onto the Ransack gem.
Edit
For future questions like "what's a popular gem for ______?", check out The Ruby Toolbox. If Ransack doesn't suit your needs, perhaps a gem in the Rails Search category has what you're looking for. I personally use Ransack for exactly what you're describing; providing a custom query interface for my application's User model.
I'd suggest doing your own search class. I find that for each app I do, the needs of search change considerably and it's simple enough to create a search app that considers all the variables you might want in a search query, posed against any number of classes you want to search.
In your Search class, have it return a collection, in the order you desire, and the collection can be made up of object instances that the searcher may desire.

How to create a tagging system like on Stack Overflow or Quora

I want to create a tagging system like seen here on Stack Overflow or on Quora. It'll be its own model, and I'm planning on using this autocomplete plugin to help users find tags. I have a couple of questions:
I want tags to be entirely user-generated. If a user inputs a new tag by typing it and pressing an "Add" button, then that tag is added to the db, but if a user types in an existing tag, then it uses that one. I'm thinking of using code like this:
def create
#video.tags = find_or_create_by_name(#video.tags.name)
end
Am I on the right track?
I'd like to implement something like on Stack Overflow or Quora such that when you click a tag from the suggested list or click an "Add" button, that tag gets added right above the text field with ajax. How would I go about implementing something like that?
I know this is kind of an open-ended question. I'm not really looking for the exact code as much as a general nudge in the right direction. Of course, code examples wouldn't hurt :)
Note I am NOT asking for help on how to set up the jQuery autocomplete plugin... I know how to do that. Rather, it seems like I'll have to modify the code in the plugin so that instead of the tags being added inside the text field, they are added above the text field. I'd appreciate any direction with this.
mbleigh's acts_as_taggable_on gem is a feature-complete solution that you should definitely look into a little more closely. The implementation is rock-solid and flexible to use. However, it is mostly concerned with attaching tags to objects, retrieving tags on objects, and searching for tagged items. This is all backend server stuff.
Most of the functionality you are looking to change (based on your comments) is actually related more to your front-end UI implementation, and the gem doesn't really do much for you there. I'll take your requests one-by-one.
If user inputs a new tag, that tag
gets added, if user inputs an
existing tag, the existing tag gets
used. acts_as_taggable_on does this.
Click a tag from suggested list to
add that tag. This is an
implementation issue - on the
back-end you'll need to collect the
suggested list of tags, then display
those in your presentation as links
to your processing function.
Autocomplete as user enters
potential tag. You'll use the jQuery
autocomplete plugin against a list
of items pulled off the tags table.
With additional jQuery, you can
capture when they've selected one of
the options, or completed entering
their new tag, and then call the
processing function.
Restrict users to entering only one
tag. This will be your UI
implementation - once they've
entered or selected a tag, you
process it. If they enter two words
separated by a comma, then before or
during processing you have to either
treat it as one tag, or take only
the text up to the first comma and
discard the rest.
When you process the addition of a
tag, you will have to do two things.
First, you'll need to handle the UI
display changes to reflect that a
tag has been entered/chosen. This
includes placing the tag in the
"seleted" area, removing it from the
"available" display, updating any
counters, etc. Second, you'll need
to send a request to the server to
actually add the tag to the object
and persist that fact to the
database (where the taggable gem will take over for you). You can either do this via
an individual AJAX request per tag,
or you can handle it when you submit
the form. If the latter, you'll need
a var to keep the running list of
tags that have been added/removed
and you'll need code to handle
adding/removing values to that var.
For an example of saving tags while editing but not sending to server/db until saving a form, you might take a look at the tagging functionality on Tumblr's new post page. You can add/remove tags at will while creating the post, but none of it goes to the database until you click save.
As you can see, most of this is on you to determine and code, but has very little to do with the backend part. The gem will take care of that for you quite nicely.
I hope this helps get you moving in the right direction.
The more I try to force the acts-as-taggable-on gem to work the more I think these are fundamentally different types of problems. Specifically because of aliases. The gem considers each tag to be its own special snowflake, making it difficult to create synonyms. In some cases it doesn't go far enough, if you want the Tag to have a description you'd need to edit the given migrations (which isn't hard to do).
Here's what I'm considering implementing, given the trouble I've had implementing via the gem. Let's assume you want to create a tagging system for Technologies.
Consider the following psuedo code, I haven't yet tested it.
rails g model Tech usage_count::integer description:text icon_url:string etc. Run the migration. Note the
Now in the controller you will need to increment usage_count each time something happens, the user submits a new question tagged with given text.
rails g model Name::Tech belongs_to:Tech name:string
Name::Tech model
belongs_to :tech
end
Then you could search via something like:
search = Name::Tech.where("name LIKE :prefix", prefix: "word_start%")
.joins(:tech)
.order(usage_count: desc)
.limit(5)
This is starting point. It's fundamentally different from the gem, as each tag is just a string on its own, but references a richer data table on the back end. I'll work on implementing and come back to update with a better solution.

Making tagsoup markup cleansing optional

Tagsoup is interfering with input and formatting it incorrectly. For instance when we have the following markup
Text outside anchor
It is formatted as follows
Text outside anchor
This is a simple example but we have other issues as well. So we made tagsoup cleanup/formatting optional by adding an extra attribute to textarea control.
Here is the diff(https://github.com/binnyg/orbeon-forms/commit/044c29e32ce36e5b391abfc782ee44f0354bddd3).
Textarea would now look like this
<textarea skip-cleanmarkup="true" mediatype="text/html" />
Two questions
Is this the right approach?
If I provide a patch can it make it to orbeon codebase?
Thanks
BinnyG
Erik, Alex, et al
I think there are two questions here:
The first Concern is a question of Tag Soup and the clean up that happens OOTB: Empty tags are converted to singleton tags which when consumed/sent to the client browser as markup gets "fixed" by browsers like firefox but because of the loss of precision they do the wrong thing.
Turning off this clean up helps in this case but for this issue alone is not really the right answer because we it takes away a security feature and a well-formed markup feature... so there may need to be some adjustment to the handling of at least certain empty tags (other than turning them in to invalid singleton tags.)
All this brings us to the second concern which is do we always want those features in play? Our use-case says no. We want the user to be able to spit out whatever markup they want, invalid or not. We're not putting the form in an app that needs to protect the user from cross script coding, we're building a tool that lets users edit web pages -- hence we have turned off the clean-up.
But turning off cleanup wholesale? Well it's important that we can do it if that's what our usecase calls for but the implementation we have is all or nothing. It would be nice to be able to define strategies for cleanup. Make that function plug-able. For example:
* In the XML Config of the system define a "map" of config names to class names which implement the a given strategy. In the XForm Def the author would specify the name from the map.
If TagSoup transforms:
Text outside anchor
Into:
Text outside anchor
Wouldn't that be bug in TagSoup? If that was the case, then I'd say that it is better to fix this issue rather than disable TagSoup. But, it isn't a bug in TagSoup; here is what seems to be happening. Say the browsers sends the following to the client:
<a shape="rect"></a>After<br clear="none">
This goes through TagSoup, the result goes through the XSLT clean-up code, and the following is sent to the browser:
<a shape="rect"/>After<br clear="none"/>
The issue is on the browser, which transforms this into:
<a shape="rect">After</a><br clear="none"/>
The problem is that we serialize this as XML with Dom4jUtils.domToString(cleanedDocument), while it would be more prudent to serialize it as HTML. Here we could use the Saxon serializer. It is also used from HTMLSerializer. Maybe you can try changing this code to use it instead of using Dom4jUtils.domToString(). You'll let us know what you find when a get a chance to do that.
Binesh and I agree, if there is a bug it would be a good idea to address the issue closer to the root. But I think the specific issue he is only part of the matter.
We're thinking it would be best to have some kind of name-to-strategy mapping so that RTEs can call in the server-side processing that is right for them or the default if it's not specified.

Acts As Taggable On: translate tags

I'm working with RoR and I was wondering how can I translate Acts As Taggable On tags without having to manually insert it every time I use a tag again?
Example:
I have a Post (title and body in English) and I create it with tags "shoes, dress, beauty".
I've title and body translated to Japanese in a text file, so I just need to copy/paste them (I'm using Globalize2 plugin to manage translations).
Then I need to add Japanese tags, so I search for translation and add it.
Now I know how to write these three words to Japanese, but I don't want to have to translate them every time I use the same tag.
Next time I create a post with the "shoes" tag, I want that the Japanese version already has the translated term.
What do you suggest? Abandon Acts As Taggable On and create a custom Tags model with a habtm relationship with Post? Subclass the Acts As Taggable On model?
Thanks in advance.
You should be able to simply create your own controller, views and routes and CRUD tags as you see fit by adding whatever fields you require to the db table with no need to subclass the tag model. Personally unless there's some fancy cloud calculation or so forth with this plugin I would roll your own as it's pretty basic. It would also be a good exercise to look through the plugin and gain an understanding of its functionality.

how to design a tag system for a localized website?

Let say i have a basic tagging system (for a craiglists "clone") such as:
Tag (id, tagname)
ad(id, title, body)
adTag(tag_id, article_id)
This will fit for a non-localized website but what will be the correct aproach for a website that is used by people speaking diferent languages?
Users probably will post ads in diferent languages in one same local area, so, maybe i should make some kind of synonym system that considers "job" and "trabajo" the same tag? But, what about users that only want to see ads in one language?
Catering for tags for all the different languages is probably just going to be trouble. Going with the idea where you treat all variations of a tag as one single type will probably simplify a lot of the issues (so you don't need to keep track of language-tag mappings on the fly, just do the conversion once and be done with it). If the user needs to search by language later on, then just stick a meta-tag for that particular language on when you save the post.
Of course, that leaves the question of what happens when a user uses tags from multiple languages... but I suppose you can always enforce one single language or something.
I can think of two possible solutions:
Add language field: Tag (id, tagname, lang) where you can specify the language for the tag
Change Tag to Tag(id) and use separate table for tag translations tagTranslations(tag_id, lang, tagname)
Note: But I think this is only needed, if your articles have multiple translations.

Resources