修改auto_complete插件,支持虚拟属性

今天用auto_complete插件实现自动补全,但是中间遇到些问题.
按照网上的方法在view里添加代码:

<%= text_field_with_auto_complete :material, :material_number %>

在controller里添加代码:

auto_complete_for :material, :material_number

开始跑一遍.试下,结果如何.
页面上没有发生变化,打开log,提示如下信息

Parameters: {"material"=>{"material_number"=>"cp"}}
Material Load (0.0ms) Mysql::Error: Unknown column 'material_number' in 'where clause': SELECT * FROM `materials` WHERE (LOWER(material_number) LIKE '%cp%') ORDER BY material_number ASC LIMIT 10

因为material_number是material表里的虚拟属性,所以上面sql语句出错.
这条sql语句应该是在auto_complete插件中实现的一个方法.
找到auto_complete的源码

module ClassMethods
def auto_complete_for(object, method, options = {})
define_method("auto_complete_for_#{object}_#{method}") do
find_options = {
:conditions => [ "LOWER(#{method}) LIKE ?", '%' + params[object][method].downcase + '%' ],
:order => "#{method} ASC",
:limit => 10 }.merge!(options)

@items = object.to_s.camelize.constantize.find(:all, find_options)

render :inline => "<%= auto_complete_result @items, '#{method}' %>"
end
end
end

原来如此,看来要自己要写一个方法了.cotroller里的代码

#自动补全
def auto_complete_for_material_material_number
@items = Material.auto_complete_material_number(params[:material][:material_number],:order => 'first_number ASC',:limit => 10)
render :inline => "<%= auto_complete_result @items, 'material_number' %>"
end

model里的代码

#material_number自动补全重写
def self.auto_complete_material_number(full_number,options = {})
find_options = {:conditions => [ "first_number LIKE ? or last_number LIKE ?",
'%' + full_number.downcase + '%' , '%' + full_number.downcase + '%' ]}.merge!(options)
# with_scope :find => options do
Material.find(:all,find_options)
# end
end

关于material_number虚拟属性的读方法也贴出来,便于理解

def material_number
[self.first_number,self.last_number].join('-')
end

再试下,看有问题没,没有提示,看log

Parameters: {"material"=>{"material_number"=>"c"}}
Material Load (0.2ms) SELECT * FROM `materials` WHERE (first_number LIKE '%c%' or last_number LIKE '%c%') ORDER BY first_number ASC LIMIT 10
Completed in 19ms (View: 1, DB: 0) | 200 OK [http://localhost/production/production_plans/auto_complete_for_material_material_number]

然后在mysql中运行上述sql语句,有结果,但是为什么没有传到前台页面呢?
应该是controller中这句代码,一步一步的分析吧.

render :inline => "<%= auto_complete_result @items, 'material_number' %>"

的原因.这个auto_complete_result是什么呢?
还是要回到源码中寻找答案.

def auto_complete_result(entries, field, phrase = nil)
return unless entries
items = entries.map { |entry| content_tag("li", phrase ? highlight(entry[field], phrase) : h(entry[field])) }
content_tag("ul", items.uniq)
end

猜想是不是这里"entry[field]",打开console,

>> material[:material_number]
=> nil
>> material.send(:material_number)
=> "cp-sj-nokia-2330"

应该是这里的问题了.
在help里增加方法

#重写自动补全
def auto_complete_result(entries, field, phrase = nil)
return unless entries
items = entries.map { |entry| content_tag("li", phrase ? highlight(entry.send(field), phrase) : h(entry.send(field))) }
content_tag("ul", items.uniq)
end

再试下,好了,ok.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值