可以通过查找我已经拥有的条目来自动完成公司。使用https://github.com/crowdint/rails3-jquery-autocomplete宝石,我添加了
autocomplete :company, :name, :scopes => [:distinct]
对我的控制器,在我的模型中,我有:
scope :distinct, lambda { select("companies.name").uniq }
使用" Merce"一词我的系统仍然返回梅赛德斯奔驰的所有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
寻找有关如何在此宝石中进行正确查询的解释。
该宝石生成的查询:
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
将始终包含" table"主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)。我可以想到两种可能解决此问题的方法:
创建一个带有子查询的查询,这个想法是创建第一个查询,然后返回唯一结果,然后将其与表ID一起连接起来,然后将其返回具有其ID的唯一名称。
在您的控制器中,重新定义了检索结果的操作,以便它执行您想要的任何操作。实际上,该GEM的作用是使用Meta编程将AutoComplete_model_attribute Action添加到您的控制器(请参阅源代码)。
希望这有助于我知道这是否有帮助。让我知道您是否需要更多详细信息。
正如上面的chischaschos所说,重新定义控制器动作是最好的课程。因为我在Heroku上使用PostgreSQL,所以我需要去做一条更复杂的路线(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上的用户也有一个较短的解决方案,这要短得多。在此处找到Orginial线程:https://github.com/crowdint/rails3-jquery-autocomplete/issues/25
更好的方法:
# model
scope :distinct_on_name, lambda {
select('DISTINCT ON (models.name) models.name, models.id')
}
# controller
autocomplete :model, :name, scopes: [:distinct_on_name]