使用rails3-autocomplete-jquery gem可以很好地处理带有多个输入的Simple_Form

所以我试图使用这个gem和simple_form实现多个自动完成,并且收到错误。

我试过这个:

 autocomplete_neighborhood_name_searches_path, :as => :autocomplete, 'data-delimiter' => ',', :multiple => true, :class => "span8" %> 

这是我得到的错误:

 undefined method `to_i' for ["Alley Park, Madison"]:Array 

在我的参数中,它是在neighborhood_id发送的:

 "search"=>{"neighborhood_id"=>["Alley Park, Madison"], 

所以它甚至没有使用这些值的ID。

有没有人有任何想法?

编辑1:

在回答@jvnill的问题时,我并没有明确地在控制器中使用params[:search]做任何事情。 搜索会创建新记录,并正在搜索listings

在我的搜索控制器中, create操作,我只是这样做:

 @search = Search.create!(params[:search]) 

然后我的search.rb (即搜索模型)有这个:

 def listings @listings ||= find_listings end private def find_listings key = "%#{keywords}%" listings = Listing.order(:headline) listings = listings.includes(:neighborhood).where("listings.headline like ? or neighborhoods.name like ?", key, key) if keywords.present? listings = listings.where(neighborhood_id: neighborhood_id) if neighborhood_id.present? #truncated for brevity listings end 

首先,如果表单返回id而不是邻域名称,这将更容易。 我还没有使用过gem,所以我不熟悉它是如何工作的。 阅读自述文件说它将返回ID但我不知道你为什么只得到名字。 我相信一旦你弄清楚如何返回id,你就可以改变下面的代码来适应这种情况。

您需要在邻域和搜索之间创建连接表。 我们称之为search_neighborhoods。

 rails g model search_neighborhood neighborhood_id:integer search_id:integer # dont forget to add indexes in the migration 

之后,您需要设置模型。

 # search.rb has_many :search_neighborhoods has_many :neighborhoods, through: :search_neighborhoods # search_neighborhood.rb belongs_to :search belongs_to :neighborhood # neighborhood.rb has_many :search_neighborhoods has_many :searches, through: :search_neighborhoods 

现在我们已经设置了关联,我们需要设置setter和属性

 # search.rb attr_accessible :neighborhood_names # this will return a list of neighborhood names which is usefull with prepopulating def neighborhood_names neighborhoods.map(&:name).join(',') end # we will use this to find the ids of the neighborhoods given their names # this will be called when you call create! def neighborhood_names=(names) names.split(',').each do |name| next if name.blank? if neighborhood = Neighborhood.find_by_name(name) search_neighborhoods.build neighborhood_id: neighborhood.id end end end # view # you need to change your autocomplete to use the getter method <%= f.input :neighborhood_names, url: autocomplete_neighborhood_name_searches_path, as: :autocomplete, input_html: { data: { delimiter: ',', multiple: true, class: "span8" } %> 

最后但并非最不重要的是更新find_listings

 def find_listings key = "%#{keywords}%" listings = Listing.order(:headline).includes(:neighborhood) if keywords.present? listings = listings.where("listings.headline LIKE :key OR neighborhoods.name LIKE :key", { key: "#{keywords}") end if neighborhoods.exists? listings = listings.where(neighborhood_id: neighborhood_ids) end listings end 

就是这样:)

更新:使用f.input_field

 # view <%= f.input_field :neighborhood_names, url: autocomplete_neighborhood_name_searches_path, as: :autocomplete, data: { delimiter: ',' }, multiple: true, class: "span8" %> # model # we need to put [0] because it returns an array with a single element containing # the string of comma separated neighborhoods def neighborhood_names=(names) names[0].split(',').each do |name| next if name.blank? if neighborhood = Neighborhood.find_by_name(name) search_neighborhoods.build neighborhood_id: neighborhood.id end end end 

您的问题是如何从邻近模型中收集值

  Neighborhood.order(:name) 

将返回一个名称数组,你还需要收集id,但只显示名称使用collect并传递一个块,我相信这可能是你的伙伴

 Neighborhood.collect {|n| [n.name, n.id]} 

如果您想要恢复该function,则在Neighborhood类上声明一个范围以按名称对其进行排序,因为该行为也无论如何都属于模型。

编辑>要将范围/类方法添加到邻域模型,您通常会这样做

 scope :desc, where("name DESC") 

比你可以写的东西:

 Neighborhood.desc.all 

这将返回一个数组,从而允许.collect但是还有其他方法可以获得select选项识别的那些name和id属性。