Rails Autocomplete Jquery (crowdint):选择 .uniq 不在范围内工作,避免重复

Posted

技术标签:

【中文标题】Rails Autocomplete Jquery (crowdint):选择 .uniq 不在范围内工作,避免重复【英文标题】:Rails Autocomplete Jquery (crowdint): select .uniq not working in scope, avoiding duplicates 【发布时间】:2012-10-11 05:33:49 【问题描述】:

公司可以通过查找我已有的条目来自动完成。 使用https://github.com/crowdint/rails3-jquery-autocomplete gem,我添加了

autocomplete :company, :name, :scopes => [:distinct]

到我的控制器和我的模型中:

scope :distinct, lambda  select("companies.name").uniq 

使用术语“Merce”,我的系统仍会返回 Mercedes Benz 的所有 5 个条目。 SQL:

35mCompany Load (4.0ms)[0m  SELECT DISTINCT companies.name, companies.id FROM "companies" WHERE (LOWER(companies.name) ILIKE 'merce%') ORDER BY companies.name ASC LIMIT 10

我尝试过的各种事情:

select(:name).uniq  => Not unique values
distinct("companies.name") => Wrong number of arguments
group(:id, :name) => Not unique values
group(:id, :name).uniq  => Not unique values

但是,在控制器中使用 select 语句(没有自动完成)可以:

@companies = Company.select(:name).uniq => Perfect results

寻找有关如何在此 gem 中进行正确查询的解释。

【问题讨论】:

【参考方案1】:

该 gem 生成的查询:

Company Load (4.0ms)  SELECT DISTINCT companies.name, companies.id FROM "companies" WHERE (LOWER(companies.name) ILIKE 'merce%') ORDER BY companies.name ASC LIMIT 10

将始终包含表主 ID 以及将自动完成的字段名称,答案在于 lines 36 and 37 of this method:

def get_autocomplete_select_clause(model, method, options)
  table_name = model.table_name
  (["#table_name.#model.primary_key", "#table_name.#method"] + (options[:extra_data].blank? ? [] : options[:extra_data]))
end

该查询结果已经是唯一的(它使用不同的名称 + id)。我可以想到两种可能的方法来解决这个问题:

    创建一个带有子查询的查询,想法是创建一个返回唯一结果的第一个查询,然后将其与表 id 进行外部联接,并返回带有其 id 的唯一名称。

    李>

    在您的控制器中重新定义检索结果的操作,以便它执行您想要的任何操作。实际上,这个 gem 的作用是使用元编程 (see source code) 将 autocomplete_model_attribute 操作添加到您的控制器。

希望这有助于让我知道这是否有帮助。如果您需要更多详细信息,请告诉我。

【讨论】:

非常感谢。你的解释是绝对正确的,然后我通过重新定义控制器来选择第二条路线。我将在下面发布我的解决方案供其他人查看。【参考方案2】:

正如上面的 Chischaschos 所说,重新定义控制器动作是最好的方法。因为我在 Heroku 上使用 PostgreSQL,所以我需要走一条由 Thuds (Thodd Huss) 开发的更复杂的路线:

当我想要超出 我实现的当前插件(例如选择不同的实体) 我自己在控制器上的自动完成方法。这只是替换 “autocomplete :organization, :city” 你通常会打的电话 你的控制器。 例如,要自动完成“不同”城市,我这样做:

def autocomplete_organization_city
 term = params[:term]
 if term && !term.empty?
  items = Organization.select("distinct city").
      where("LOWER(city) like ?", term.downcase + '%').
      limit(10).order(:city)
 else
 items = 
 end
render :json => json_for_autocomplete(items, :city)
end

对于 SQLite 上的用户,还有一个更短的解决方案,它要短得多。在这里找到原始线程: https://github.com/crowdint/rails3-jquery-autocomplete/issues/25

【讨论】:

【参考方案3】:

更好的方法:

  # model
  scope :distinct_on_name, lambda 
      select('DISTINCT ON (models.name) models.name, models.id')
  
  # controller
  autocomplete :model, :name, scopes: [:distinct_on_name]

【讨论】:

以上是关于Rails Autocomplete Jquery (crowdint):选择 .uniq 不在范围内工作,避免重复的主要内容,如果未能解决你的问题,请参考以下文章

如果没有可用数据,rails3-jquery-autocomplete 清除字段

在不同的模型/控制器上使用 rails-jquery-autocomplete

[Ruby on Rails] 找不到类型为“application/javascript”的文件“jquery-ui/autocomplete”

rails-jquery-autocomplete 搜索 school_name 但保存 school_id

Rails Autocomplete Jquery (crowdint):选择 .uniq 不在范围内工作,避免重复

如何在rails应用程序中使用jquery自动完成