Tagging with autocomplete in Rails - ruby-on-rails

My (long, I apologize) question is a follow-on to: How to add tagging with autocomplete to an existing model in Rails?
I am using acts-as-taggable-on and rails3-jquery-autocomplete, and trying to set up a system (much like Stack Overflow) where users begin to enter in a tag and suggestions appear in a drop-down box.
Goal
I am in the answers#new form and I want to see a list of tags that relate to questions. i.e. Imagine being on SO looking for new Rails questions to answer, and searching for ra. Ruby-on-Rails pops up, you click it, and you see a list of questions under RoR, any one of which you can answer.
These are the steps I've taken.
Installed both gems. Both seem to work on their own.
Added <%= javascript_include_tag "ui/jquery.ui.position", "ui/jquery.ui.autocomplete", "autocomplete-rails.js", "rails.js", "application.js" %>. (I already have Jquery, UI Core and UI Effects.)
Answers controller: I added at top autocomplete :question, :tags, :full => true. I also tried autocomplete :tag, :name, :full => true.
Question.rb: acts_as_taggable_on :tags.
View:
<%= form_tag new_answer_url, :method => "get" do %>
<%= autocomplete_field_tag "tag_list", 'tags', autocomplete_question_tags_answers_path %>
<% end %>
A simple autocomplete (no tagging) works (but it only works once per page load). With tagging, no success.
Problems
With lots of experimentation (and many hours) I am getting these problems:
I get NameError (unitialized constant Tag) in server response to initial entry.
With a non-taggable implementation (searching for the simple question text itself) I get a JQuery Autocomplete-style drop-down but my cursors cannot access the options with up/down. I have to click them with the mouse. Also, the dropdown doesn't disappear unless I reload the page!
After the server responds with results once (only non-taggable is working as I mentioned), it doesn't respond again to key presses or changes in the text entry.
I would greatly appreciate any help you are able to give. I have gone through a few tutorials step-by-step but no luck today.

I know it only answers one of your questions, but I was able to solve the "unitialized constant Tag" issue by explicitly specifying the class name in my controller:
autocomplete :tag, :name, :class_name => 'ActsAsTaggableOn::Tag'
It seems some of the changes to the acts_as_taggable_on library broke the underlying assumption that the Tag class exists.
Beyond that, I noticed some strange behavior myself when I didn't have my jquery-ui css correctly included on the pageā€”have you verified that everything's getting linked in properly?

One thing I notice you're missing is anything your routes. I had to put something like this:
resources :resources do
get :autocomplete_resource_tag, :on => :collection
end
In my _form.html.erb
<%= f.autocomplete_field :tag_list, autocomplete_resource_tag_resources_path %>
Now my problem is that the autocomplete still isn't loving me
SQLite3::SQLException: no such column: resources.tag: SELECT resources.id, resources.tag FROM "resources" WHERE (LOWER(resources.tag) LIKE 'woo%') ORDER BY resources.tag ASC LIMIT 10
Completed 500 Internal Server Error in 1ms
ActiveRecord::StatementInvalid (SQLite3::SQLException: no such column: resources.tag: SELECT resources.id, resources.tag FROM "resources" WHERE (LOWER(resources.tag) LIKE 'woo%') ORDER BY resources.tag ASC LIMIT 10):

Related

Rails collection_select: using 'prompt' with logic - is there a better way?

So, I am using a form_tag to create my own search facility on a site displaying items.
I have a collection_select which lists locations of the items. I initially used prompt: 'n/a' to display 'n/a' without adding 'n/a' into the list of locations and then tried to use select: params[:search][:location] to keep the selection in the list after submitting. Basically I could get one of them to work at a time. Never both. I have written a work-around below:
<%= collection_select(:search, :location, Item::LOCATIONS, :to_s, :titleize, prompt: (#location ? params[:search][:location] : 'n/a')) %>
This is working but it feels wrong. I have obviously created a variable called #location in the controller for when the params exist and then added logic into the collection_select tag.
Any cleaner solutions to this would be appreciated. I am very new to Rails (and coding!) so trying to learn best practices.

activeadmin rails 4 understanding how to create custom forms

I am new to activeadmin / formtastic and I have having a bit of trouble understanding how things work. I read through the documentation on how to create a form using formtastic but I seem to be still running into issues and I am sure its me not understanding how things work.
I am creating a discussions application very similar to a blog application and the end result is that I would like to create an interface for the administrators to add comments to discussions without having to go into the users interface.
My starting point is the discussions view in the admin section presented by activeadmin. I am attempting to work on the add comment form. According to the instructions, I should be able to add a form using
form partial: 'new_admin_comment_form', locals {discussion_comment: DiscussionComment.new}
which then I should create this partial in app/views/admin/discussions folder. I have done that and have entered some arbitrary text to make sure the partial renders and it does. But once I start adding code I am not able to get the form to display.
The current code I am working with is:
<%= semantic_form_for [:admin, discussion_comment] do |f| %>
<%= f.inputs, :body %>
<%= f.actions %>
<% end %>
So a few questions I have that I wasn't able to find in the documentation:
Where do I create instance variables to be used in my form? I have been setting these in the activeadmin files and that is bothering me.
How do I pass params around? I assumed I could do this as normal yet when I try to view them using <%= debug params.inspect %>, it is empty even when I should have at least the id that was in the parent form. Even when using locals: {id: params[:id]}, id is empty in the partial.
What are the best ways to debug why my form is not appearing? Am I able to use regular ERB if worse comes to worse?
You can do this without a custom form. If you stick to the active admin DSL you can use its has_many method. Example here:
http://www.activeadmin.info/docs/5-forms.html
Your Discussion model should look like this
class Discussion < ActiveRecord::Base
has_many :discussion_comments
accepts_nested_attributes_for :discussion_comments, allow_destroy: true
end

Kaminari pagination with fields_for

I have a form for a company model:
<%= form_for(#company) do |f| %>
I also have a fields_for section to edit the imports relation:
<%= f.fields_for(:imports) do |builder| %>
Company has_many :imports
and
Import belongs_to :company
I want to use Kaminari for pagination, but the problem is, Kaminari needs a page object returned from the controller like such:
#imports = Import.where(:company_id => current_user.company.id).page(params[:page]).per(50)
This allows me to use the paginate method from Kaminari:
<%= paginate #imports %>
That works, and displays the page links on my form, however, they are obviously not linked to my fields_for block.
My question is, how can I accomplish pagination with a fields_for block?
I need to allow the user to edit a list of Import models, and there will probably be too many to fit on one page which is why I'm trying to paginate. Basically I'm trying to create a spreadsheet like experience for the user.
I don't need to use Kaminari, but I'm on Rails 3.1 and it seemed to be the popular choice.
Thanks for any help on this.
You can use 'fields_for` with a collection of objects as well.
So you can do
<%= f.fields_for(:imports, #imports) do |builder| %>
If that answers your question then you're done! However if you want it to be a 'spreadsheet' like ordeal then maybe not so much.
The problem being that if you do that each time you go to a new page you will lose all your edited imports.
It may be simpler to do this:
Build all the fields_for and hide them.
Then build your own AJAX 'pagination'.
That way when the submit the changes it will pass all the imports and their changes instead of just the current page.

Using Formtastic to select from a radio set and optionally create a new record

I've begun using Formtastic in the last couple days and have come to my first head-scratcher.
I'm working with items that each have a few associated accounts. On the page in question you need to select a payee account. It can either be an account we already know about (the "Main Contact") or a new account that you can create by filling in a little information.
Here's the design I'm trying to replicate:
Using Formtastic it's very simple to display a form to enter a new account's information.
<%= form.inputs :street, :city, :for => :address %>
It's also very simple to create a radio selection list of available accounts.
<%= form.input :address, :as => :radio, :collection => #addresses %>
The problem I'm puzzling over, as the above pic illustrates, is how to do both - select an existing account or create a new one.
Well, the real question is how to do both gracefully. Anything I've thought of seems to add logic to the controller and leaves me suspecting that there's a graceful solution that I'm not seeing (having dived into RoR recently, this is a very familiar feeling).
Can't see a solution that wouldn't add a few lines to a controller. Although "Fat models, thin controllers" is a nice principle, it's not always possible to have "one-liner" restful methods, with a before filter on top setting up variables for views.
So what "level of gracefulness" we are talking about? ;) Maybe you could post a solution you consider and other members would comment on it or rate it?

How do I implement text fields with autocomplete for habtm fields?

I tried the example from Rails Cookbook and managed to get it to work. However the text_field_with_auto_complete works only for one value.
class Expense < ActiveRecord::Base
has_and_belongs_to_many :categories
end
In the New Expense View rhtml
<%= text_field_with_auto_complete :category, :name %>
Auto complete works for the first category. How do I get it working for multiple categories? e.g. Category1, Category2
Intended behavior: like the StackOverflow Tags textbox
Update:
With some help and some more tinkering, I got multiple comma-seperated autocomplete to show up (will post code-sample here).
However on selection, the last value replaces the content of the text_field_with_auto_complete. So instead of Category1, Category2.. the textbox shows Category2 when the second Category is selected via auto-complete. Any ideas how to rectify this?
If you are just trying to support multiple instances of autocomplete per field, you can pass a delimiter to the autocomplete options with the symbol :token. This provides a delimiter to allow multiple results. Stackoverflow would use :token => ' ' (there should be a space between the quotes, but the autoformat is removing it) to specify space at the delimiter between multiple takes although ',' is more commonly used.
This is not quite your question, but I wouldn't recommend using HABTM anymore. You should create a join model and use has_many :through. (In your case you'd create a new model called ExpenseCategoryAssignment, or something)
The problem is that HABTM creates ambiguities that rails doesn't like, and it tends to expose bugs you wouldn't see otherwise.
You need to use "data-delimiter" param like this
<%= f.autocomplete_field :brand_name, welcome_autocomplete_brand_name_path, "data-delimiter" => ', ' %>

Resources