I have a form with a task(uses Rails4 autocomplete gem) and a project text_field. I want to be able to fill it just from selecting a task.
So if I have
When I type 'ta', and select task1 from the autocomplete, I want the project field to be filled with the correspondent project (project1 in this case).
This is the form:
<%= form_for :instance, url: instances_path do |f| %>
<%= f.label :task_name %>
<%= f.autocomplete_field :task_name, autocomplete_task_name_static_pages_path %>
<%= f.text_field :project_name %>
<% end %>
And this is the controller:
class StaticPagesController < ApplicationController
autocomplete :task, :name
end
Reading the documentation I've tried adding :
:display_value => :task_full_info
and
class Task < ActiveRecord::Base
belongs_to :project
def task_full_info
self.project.name
end
end
But that doesn't work. What's the proper way of doing it on Rails 4 with the rails4-autocomplete gem? Also, what changes should I make if I change the project text_field to a dropdownlist?
EDIT: Server log:
Started GET "/static_pages/autocomplete_task_name?term=do" for ... at 2016-05-05 18:05:50 -0300
Processing by StaticPagesController#autocomplete_task_name as JSON
Parameters: {"term"=>"do"}
User Load (1.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Task Load (0.4ms) SELECT "tasks"."id" as id, "tasks"."name" as name, "project_name", "tasks"."project_id" FROM "tasks" WHERE (LOWER(name) LIKE 'do%') ORDER BY LOWER(name) ASC LIMIT 10
Project Load (0.3ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT 1 [["id", 7]]
Completed 200 OK in 10ms (Views: 0.3ms | ActiveRecord: 1.9ms)
From the documentation you linked, I see here what you want to do with :project_name
. So your code would look something like:
<%= form_for :instance, url: instances_path do |f| %>
<%= f.label :task_name %>
<%= f.autocomplete_field :task_name, autocomplete_task_name_static_pages_path, :update_elements => {:project_name => '#instance_project_name'} %>
<%= f.text_field :project_name %>
<% end %>
I'm assuming here that instance_project_name is the actual id of the :project_name
text field (it should if the code is as you stated).
class StaticPagesController < ApplicationController
autocomplete :task, :name, :extra_data => [:project_id, :project_name]
end
class Task < ActiveRecord::Base
belongs_to :project
delegate :name, to: :project, prefix: true
end
I'd also recommend you to change your gem to this one, since it's linked from the documentation and seems to be more updated than the one you are using.
Update:
As it turns out, the gem does the following when autocomplete triggers:
1) Makes an Activerecord select
given the autocomplete field and what's given on the extra_data
option. So that's why the weird "project_name"
in the Task
query from your log.
2) Then it takes that Activerecord result and uses the send
method for each requested field (again, the autocomplete field and the ones specified on extra_data
).
That's why whenever you need a field from a joined table, as a workaround, it's required that you put on extra data the foreing_key, since otherwise 1) won't have access to that foreign key and when 2) it's executed it won't find the association.
I guess the gem could be improved by always selecting all foreign keys in 1) query but for now you'll have to settle with the workaround.