3

公司可以通过查找我已经拥有的条目来自动完成。使用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 中进行正确查询的解释。

4

3 回答 3

4

该 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 加上将自动完成的字段的名称,答案在此方法的第 36 和 37 行

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)。我可以想到两种可能的方法来解决这个问题:

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

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

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

于 2012-10-23T13:39:50.417 回答
4

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

当我想要超出当前插件功能的自定义自动完成(例如选择不同的实体)时,我在控制器上实现了我自己的自动完成方法。这只是替换了您通常放入控制器中的“自动完成:组织,:城市”调用。例如,要自动完成“不同”的城市,我这样做:

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

于 2012-11-06T13:25:55.983 回答
2

更好的方法:

  # model
  scope :distinct_on_name, lambda {
      select('DISTINCT ON (models.name) models.name, models.id')
  }
  # controller
  autocomplete :model, :name, scopes: [:distinct_on_name]
于 2015-05-05T09:56:43.220 回答