Getting rails3-autocomplete-jquery gem to work with Simple_Form with multiple inputs

So I am trying to implement multiple autocomplete using this gem and simple_form and I am getting an error.

I've tried this:

<%= f.input_field :neighborhood_id, collection: Neighborhood.order(:name), :url => autocomplete_neighborhood_name_searches_path, :as => :autocomplete, 'data-delimiter' => ',', :multiple => true, :class => "span8" %>

      

This is the error I am getting:

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

      

In my parameters, it sends this to neighborhood_id

:

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

      

So it doesn't even use IDs for these values.

Does anyone have any ideas?

Edit 1:

In response to @jvnill's question, I am not doing anything with params[:search]

in the controller. Search creates a new record and performs a search listings

.

In my controller Searches, create

action, I just do this:

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

      

Then mine search.rb

(i.e. the search model) has the following meaning:

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

      

0


source to share


2 answers


First of all, it would be easier if the form returns IDs instead of the neighborhood name. I have not used this stone yet, so I don’t know how it works. Reading in the readme says it will return ids, but I don't know why you are only getting names. I'm sure that once you know how to return ids, you can modify the code below to match.

You need to create a join table between neighborhood and lookup. Let's call this search_neighborhoods.

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

      

After that, you want to customize your models.

# 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

      

Now that we have established the associations, we need to configure the setters and attributes



# 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" } %>

      

the last but not the last is an update 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

      

What is it:)

UPDATE: Using 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

      

+1


source


Your problem is how you collect values ​​from the neighborhood of Model

 Neighborhood.order(:name)

      

will return an array of names, you need to collect the id as well, but just display the names use collect and skip block, i believe this can do for you

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

      

Declare a region in the Neighborhood class to order it by name if you want to return its functionality, as this behavior is also present in the model.



edit> To add a scope / class method to the neighborhood model you usually do something like this

scope :desc, where("name DESC")

      

Than you can write something like:

Neighborhood.desc.all

      

which will return an array, which will allow .collect to be used, but there is another way to get those name and id attributes recognized by the select option.

0


source







All Articles