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