Ruby on Rails - 简单表单自动完成关联搜索

Posted

技术标签:

【中文标题】Ruby on Rails - 简单表单自动完成关联搜索【英文标题】:Ruby on Rails - Simple Form autocomplete association search 【发布时间】:2015-06-29 00:22:34 【问题描述】:

我在一个基本任务管理应用程序中有一个表单,它允许将任务分配给用户(任务属于用户)。我正在为此使用简单表单。

目前,关联以典型方式填充,用户下拉列表如下:<%= f.association :user, label_method: :name, value_method: :id, include_blank: false %>

但是,随着用户数量的增长,我希望将其更改为自动填充表单字段以查找用户。我已尝试关注Railscast on the subject,尽管它不使用简单表单并且无法用于我的实现。

这是我的表格、型号和 .coffee 代码:

表格

<%= simple_form_for @task do |f| %>
  ...
  <%= f.input :user_name, as: :search, data: 
      autocomplete_source: User.pluck(:name) %>
  ...
  <%= f.button :submit %>
<% end %>

型号

# Virtual attribute for autocomplete form field
  def user_name
    user.try(:name)
  end

  def user_name=(name)
    self.user = User.find_by_name(name) if name.present?
  end

tasks.coffee

jQuery ->
  $('#task_user_name').autocomplete
    source: $('#task_user_name').data('autocomplete-source')

这会生成以下 html

<input class="string search optional form-control 
ui-autocomplete-input ui-autocomplete-loading" type="search" 
value="Robert Strong" name="task[user_name]" id="task_user_name" 
autocomplete="off">

虽然开发工具控制台中出现以下错误:

Uncaught TypeError: this.source is not a function

关注 HTML 中的 autocomplete="off",无法想象 TypeError 有多大帮助!

我被难住了,所以非常感谢任何关于让它工作的建议!提前谢谢,让我知道你的想法,史蒂夫。

【问题讨论】:

【参考方案1】:

autocomplete_source 需要一个数组或 URL,当调用该数组或 URL 时,它会返回带有与查询匹配的结果的 JSON。 http://api.jqueryui.com/autocomplete/#option-source

现在你有

  <%= f.input :user_name, as: :search, data: 
  autocomplete_source: User.pluck(:name) %>

那可能会为 javascript 返回一个字符串。因此,您可以将其更改为:

  <%= f.input :user_name, as: :search, data: 
  autocomplete_source: User.pluck(:name).to_json %>

然后在设置自动完成时解析该 JSON:

jQuery ->
  $('#task_user_name').autocomplete
    source: JSON.parse($('#task_user_name').data('autocomplete-source'))

但从长远来看(当您有很多用户时),这会显着影响您页面的加载时间。您实际上应该遵循该 railscast 并将 URL 作为自动完成源:

  <%= f.input :user_name, as: :search, data: 
  autocomplete_source: users_path %>

确保将 json 渲染路径添加到用户控制器上的索引操作。

如果您的索引操作也用于其他用途,您可以使用respond_to

# users_controller
def index
  @users = User.order(:name)
  @users = @users.where("name like ?", "%#params[:term]%") if params[:term]

  respond_to do |format|
    format.html  # index.html.erb
    format.json   render :json => @users.map(&:name) 
  end
end

【讨论】:

这是一个很棒的答案。完美运行,我听从了您的建议并呈现了 URL 中的信息。非常感谢奥利弗的努力。 很高兴我能帮上忙!玩得开心编码! 我希望在实现我在表单中有一个 jquery 自动完成字段然后更新隐藏的关联字段的糟糕的 hacky 方法之前阅读了这篇文章。将使用此解决方案进行重构。谢谢!【参考方案2】:

除了奥利弗的回答,我还必须:

<%= f.input :user_name, as: :search, input_html: class: 'ui-autocomplete-input', data: autocomplete_source: users_path %>

使其与 Simple_Form 一起使用。

【讨论】:

以上是关于Ruby on Rails - 简单表单自动完成关联搜索的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试从 ruby​​ on rails 上的表单获取输入时,我得到了简单名称的哈希数组瞬间。如何解决?

如何使用 Ruby on Rails 5 将数据从 URL 提取到表单中

Ruby on Rails 表单中的 select 和 onChange

几个拥有大型 JQuery 自动完成数据集的用户降低了整个 Ruby on Rails 应用程序的速度

Angular.js 与 Ruby On Rails 表单的集成

如何使下拉表单在 Ruby On Rails 中工作