多字段自动完成的完整实现:
根据我的评论,我集成到 jquery-autocomplete 的解决方案是自定义实现“内部”自动完成。
1.查询数据库
如果您使用 ActiveRecord,您可以为您的 named_scope 使用 DGM 的解决方案
如果您使用的是 Mongoid,则可以改用以下语法:
scope :by_first_name, ->(regex){
where(:first_name => /#{Regexp.escape(regex)}/i)
}
scope :by_last_name, ->(regex){
where(:last_name => /#{Regexp.escape(regex)}/i)
}
scope :by_name, ->(regex){
any_of([by_first_name(regex).selector, by_last_name(regex).selector])
}
EDIT :如果您想要更强大的自动完成功能,可以处理重音、匹配部分文本等;你应该试试 mongoid 文本索引。感谢the original answer there
index(first_name: 'text', last_name: 'text')
scope :by_name, ->(str) {
where(:$text => { :$search => str })
}
添加rake db:mongoid:create_indexes后不要忘记建立索引
所以你基本上可以做到User.by_name(something)
2。在控制器中创建自动完成操作
因为 jquery-autocomplete 提供的...不会做我们想做的事。
请注意,您必须将结果转换为 JSON,以便在前端 jquery-autocomplete 中使用。为此,我选择使用 gem ActiveModel::Serializer,但如果您愿意,可以随意使用其他东西,并跳过第 3 步
在您的控制器中:
def autocomplete
@users = User.by_name(params[:term])
render json: @users, root: false, each_serializer: AutocompleteSerializer
end
3。重新格式化响应
您使用 gem activemodel 的序列化程序:
我提供了 0.9 版本的链接,因为 master 主页不包含完整的文档。
class AutocompleteSerializer < ActiveModel::Serializer
attributes :id, :label, :value
def label
object.name
# Bonus : if you want a different name instead, you can define an 'autocomplete_name' method here or in your user model and use this implementation
# object.respond_to?('autocomplete_name') ? object.autocomplete_name : object.name
end
def value
object.name
end
4.为您的自动完成创建路线
在您的路线中:
get '/users/autocomplete', to: 'users#autocomplete', as: 'autocomplete_user'
5.在你的观点中玩得开心
最后在你的视图中你可以使用jquery-rails的默认语法,但是记得改变路径!
<%= form_tag '' do
autocomplete_field_tag 'Name', '', autocomplete_user_path, :id_element => "#{your_id}", class: "form-control"
end %>
RQ :我使用了一些 2 级深度嵌套形式,因此获得正确的 id 元素 your_id 有点棘手。就我而言,我不得不做一些复杂的事情,但很可能对你来说很简单。您可以随时查看生成的 DOM 以检索字段 ID