Как заполнить ввод текста из другого автозаполнения Rails 4

У меня есть форма с задачей(использует Rails4 autocomplete gem) и text_field проекта. Я хочу, чтобы иметь возможность заполнить его только от выбора задачи.

Так что если у меня есть

  • task1: project1

Когда я набираю » ta » и выбираю task1 из автозаполнения, я хочу, чтобы поле проекта было заполнено соответствующим проектом ( project1 в этом случае).

Это форма:

<%= 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 %>

А это контроллер:

class StaticPagesController < ApplicationController
  autocomplete :task, :name
end

Чтение документации, которую я пытался добавить :

:display_value => :task_full_info

и

class Task < ActiveRecord::Base 
  belongs_to :project

  def task_full_info
    self.project.name
  end
end

Но это не работает. Как правильно сделать это на Rails 4 с помощью rails4-autocomplete gem? Кроме того, какие изменения следует внести в раскрывающийся список проекта text_field?

РЕДАКТИРОВАТЬ:
Журнал сервера:

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)

1 ответ

  1. Из документации, которую вы связали, я вижу, что вы хотите сделать :project_name. Таким образом, ваш код будет выглядеть примерно так:

    <%= 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 %>
    

    Я предполагаю, что instance_project_name является фактическим идентификатором :project_nameтекстового поля (он должен, если код таков, как вы сказали).

    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
    

    Я также рекомендую вам изменить свой драгоценный камень на этот, так как он связан с документацией и кажется более обновленным, чем тот, который вы используете.

    Обновление:

    Как оказалось, gem делает следующее при автозаполнении триггеров:

    1) делает Activerecord selectзаданное поле автозаполнения и то, что дано на extra_dataопции. Так вот почему странные "project_name"в Taskзапросе из вашего журнала.

    2) Затем он берет этот результат Activerecord и использует sendметод для каждого запрошенного поля (опять же, поле автозаполнения и те, которые указаны наextra_data).

    Вот почему всякий раз, когда вам нужно поле из присоединенной таблицы, как обходной путь, требуется, чтобы вы положили на дополнительные данные foreing_key, так как в противном случае 1) не будет иметь доступа к этому внешнему ключу, и когда 2) он выполнен, он не найдет связь.

    Я думаю, что драгоценный камень может быть улучшен, всегда выбирая все внешние ключи в 1) запрос, но сейчас вам придется согласиться с обходным путем.