Parsing blog post tags from a text_field - ruby-on-rails

Ok, so you know how you ask a question here, and in the "Tags" field you can enter several space-separated tags into a single text field?
I'm trying to replicate similar behavior in my Rails app. Except instead of questions, I'm doing a blog app (which has "posts"), and tagging those.
I'm using "form_for" to build the quick form. Inside of that I have the line:
f.text_field :tags
The problem I'm running into is, "tags" is not a field on my Post class. My Post class HABTM tags. So, somehow I need to parse the tags text field (using String.split), and pass the resulting tag Strings into my controller, so my controller can create and associated the tags along with the new blog post.
Is using "form_for" not going to work in this case? Is doing this sort of behavior beyond the design of the quick-and-dirty "form_for" functionality?
Thanks!

Unless you really want to reinvent the wheel, I would suggest using a plugin for this. ActsAsTaggableOnSteroids is a mature one. http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids

Agree with Ben on this - there's lots of great plugins and features/helpers that make them simple to use. And you can learn a lot about how to do this in a well-designed way. Here's another good choice.
http://github.com/mbleigh/acts-as-taggable-on

Related

Is there a Rails way of making a form with a nested polymorphic relation (new or existing)?

I have a model Navigation that has a polymorphic target. That target can be a Page, an ExternalLink, or a Plugin. Each of these targets has different attributes (page has content, title, external link has title, url, plugin has its own polymorphic relations.
I'm building a little form to add a Navigation link, and I want to give my users the option to select an existing one of these relations (which is easy enough, just a grouped collection select), but I also would like to let them select a 'New' option for each of these target models.
The question is -- how do I include it in the same form?
I could make a form object, but that feels like the last-resort option. I know I can accept nested attributes for target, but I don't know how to do that with a selection form as well. I know I could do some js hackery to add or remove form elements on selecting or not selecting the 'new' options.
All of these don't feel railsey. This problem feels like a not-uncommon issue, and I imagine this is a solved problem that I'm trying to reinvent the wheel for. What option am I missing? What is the rails way to make this?
You may want to look at the Cocoon gem, will handle a lot of the "js hackery" you alluded to.
This post shows how to use Cocoon to render the appropriate fields for (in your case) each of the possible target classes.
Whether you have a separate button for each target class is up to you.
I think you should use globalid gem for this.
Here is a good article describing how it works.
GlobalID helps you uniquely identify your models. E.g. gid://Company/1 and gid://Employee/1 has the same IDs, but different GlobalIDs. You can actually find model simply by using GlobalID::Locator:
GlobalID::Locator.locate gid_value
This should make simple combo-boxes easily programmable.

Reference ActiveRecord attributes in textarea

I am building a simple invoice application, and I would like to allow the users to customize the text on the invoice. In addition to this, they should be able to reference specific attributes in my models, i.e. "This is a test {{Model.attribute}}", and once the text is parsed the tag is replaced with the value of that attribute.
I have looked a bit at redcloth, textile and handlebars, but it does look like a little bit overkill to be honest. For instance I would not like to allow the users to input any HTML.
I would really appreciate if someone could point me in the right direction. There is probably a gem for this that I just havent found yet.
Thanks in advance
I use liquid with simpleformat which will sanitise the text.

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.

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.

Best way to implement simple sorting / searching in Rails

What's the best way to implement an interface that looks like this in rails?
Currently I'm using Searchlogic, and it's a tad painful. Problems include:
Making sure certain operations remain orthogonal -- for example, if you select "Short Posts" and then search, your search results should be restricted to short posts.
Making sure the correct link gets the "selected" class. Right now the links are <a>'s, so maintaining this state client-side is tricky. I'm hacking it by having the AJAX response to, say, sorting return a new sort links section with the correct link "selected". Using radio buttons instead of <a> tags would make it easier to maintain state client-side -- maybe I should do that?
I recently solved a similar problem using named_scopes and some ruby metaprogramming that I rolled up into a plugin called find_by_filter.
find_by_filter accepts a hash of scope
names and values, and chains them into
parametised scope calls. If the model has a named_scope that matches the provided name, this is called.If no named_scope is found, an anonymous scope is created.

Resources