Search on multiple keywords in a single search tex

2020-02-11 07:23发布

问题:

I'm fairly new and playing around with searching databases in Rails. I have a model and database that has a list of names under the 'name' attribute. I want to be able to enter search keywords into a single search field and this input can be one word or two words or more, depending on how specific a result the user wants.

Right now, I'm using something ugly as shown below, which will do a maximum of 3 search terms. Is there a way to make this dynamic for 'search_length' keywords? The find method is clearly repetitive, but I'm not sure how to automate it and haven't found any useful suggestions elsewhere online.

def self.search(search)

  if search
    search_length = search.split.length
    find(:all, :conditions => ['name LIKE ? AND name LIKE ? AND name LIKE ?', 
    "%#{search.split[0]}%", "%#{search.split[1]}%", 
    "%#{search.split[search_length1]}%"])
  else
    find(:all)
  end
end

Other than this, loving Rails so far.

Thanks Much, Lev

回答1:

The code from Łukasz Śliwa works great if you close the name variable with the other % sign.

The complete code from above working for me. Great post.

def self.search(search)

  if search
    search_length = search.split.length
    find(:all, :conditions => [(['name LIKE ?'] * search_length).join(' AND ')] + search.split.map { |name| "%#{name}%" })
  else
    find(:all)
  end

end


回答2:

Use something like this:

find(:all, :conditions => [(['name LIKE ?'] * search_length).join(' AND ')] + search.split.map { |name| "%#{name}" })

I looks strange but, first generate search_length times string 'name LIKE ?':

 ['name LIKE ?'] * search_length

then you have array with some keys, so let's join all of them with ' AND ':

 ["name LIKE ? ", "name LIKE ? ", "name LIKE ? "].join(' AND ')

and finally merge with another array.



回答3:

formatted_columns = format_column_names(Sub.column_names)
where(formatted_columns.map {|cn| "#{cn} like ?" }.join("or "), *(["%#{search}%"] * formatted_columns.size))

this takes care of all columns as well as the correct amount of fields