Rails高级搜索未返回所需的结果

时间:2017-03-08 02:21:20

标签: ruby-on-rails ruby ruby-on-rails-5 advanced-search

这是我第一次实施高级搜索。我正在模仿宠物发现者,但对于狗而言,希望搜索功能类似于宠物发现者搜索宠物的搜索功能。我期望的结果是让用户输入他们所期望的偏好,关于他们正在寻找什么样的狗(品种,年龄,性别,位置等)以及当他们点击搜索时,它重定向并呈现他们想要的狗。我没有得到任何错误,只是没有得到理想的结果。

如果您需要其他信息,请与我们联系。

我想补充一点,如果我在searchs_controller.rb中取出if语句并且只有:@dogs = Dog.search(params[:location], params[:breed], params[:age], params[:gender]).all那么它会给我这个错误:

ActionView::Template::Error - PG::UndefinedFunction: ERROR:  operator does not exist: integer ~~ unknown
LINE 1: ...n LIKE '%92603%' AND breed LIKE '%corgi%' AND age LIKE '%Bab...
                                                             ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
: SELECT "dogs".* FROM "dogs" WHERE (location LIKE '%92603%' AND breed LIKE '%corgi%' AND age LIKE '%Baby%' AND gender LIKE '%female%'):

应用程序/控制器/ searchs_controller.rb

class SearchsController < ApplicationController

    def index
      if params[:search]                                                                                                                                    
         @dogs = Dog.search(params[:location], params[:breed], params[:age], params[:gender]).all
      else
          @dogs = Dog.all.order("age ASC")
       end
    end
end

应用程序/模型/ dog.rb

在:

class Dog < ApplicationRecord

  def self.search(location, breed, age, gender)                                                                                                           
    return all unless location.present? || breed.present? || age.present? || gender.present?
    where(['location LIKE ? AND breed LIKE ? AND age LIKE ? AND gender LIKE ?', "%#{location}%", "%#{breed.downcase}%", "%#{age}%", "%#{gender.               downcase}%"])
  end

end

之后:

def self.search(location, breed, age, gender) 
    return all unless location.present? || breed.present? || age.present? || gender.present?
    where('location @@ ? AND breed @@ ? AND age = ? AND gender @@ ?', location, breed.downcase, age, gender.downcase)
  end

应用程序/视图/ searchs / index.html.erb

<div class="doge-info">
   <% @dogs.each do |d| %>                                                                                                                                 
      <h2>Meet: <%= d.name %></h2>
      <h4><%= d.name %> is a <%= d.breed %></h4>

      <% if d.gender.titleize == "Female" %>
        <h4>She is <%= d.age %> years old.</h4>
      <% else %>
        <h4>He is <%= d.age %> years old.</h4>
      <% end %>

   <% end %>
 </div>

应用程序/视图/狗/ _form.html.erb

03/08更新:

<div class="search-for-dogs-form">
  <%= form_tag searchs_index_path, method: "get", class: "search-dogs" do %>

    <div id="form-searching-for-dogs">

      <div class="location">
        <% label_tag :location, class: "location-label" %>
        <%= number_field_tag :location, params[:location], max: 0..5, placeholder: "Zip Code", class: "zip-code-area" %>
      </div>

      <div class="dog-breed">
        <% label_tag :breed, class: "breed-label" %>
        <%= text_field_tag :breed, params[:breed], placeholder: "Breed", class: "breed-text-field" %>
      </div>

      <div class="dog-age">
        <p class="age-name">Choose an Age Range:</p>
        <%= radio_button_tag :age, "#{0..2}" %>
        <%= label_tag :age_baby, "0-2 years", class: "age-baby" %>
        <%= radio_button_tag :age, "#{3..5}" %>
        <%= label_tag :age_young, "3-5 years", class: "age-young" %>
        <%= radio_button_tag :age, "#{6..8}" %>
        <%= label_tag :age_adult, "6-8 years", class: "age-adult" %>
      </div>

      <div class="dog-gender">
        <% label_tag :gender, class: "gender-label" %>
        <%= text_field_tag :gender, params[:gender], placeholder: "Dog Gender", class: "gender-text-field" %>
      </div>

      <div class="submit-button-for-search">
        <%= submit_tag "Search for Dogs", name: nil, class: "dog-search-submit-button" %>
      </div>
    </div>
  <% end %>
</div>

应用程序/配置/ routes.rb中

   devise_for :admins
   root to: 'homepages#index'

   resources :dogs, only: [:index, :show]
   get "searchs/index"

   namespace :admin do
     resources :dogs
   end

分贝/ schema.rb

create_table "dogs", force: :cascade do |t|
    t.string "name"
    t.integer "age"
    t.string "breed"
    t.string "gender"
    t.boolean "adoptable"
    t.datetime "post_date"
    t.string "color"
    t.string "size"
    t.string "birth_date"
    t.string "photo"
    t.string "location"
  end

2 个答案:

答案 0 :(得分:1)

您使用的是Postgresql,LIKE的工作方式与MYSQL相同。您需要使用ilike@@

where(['location LIKE ? AND breed LIKE ? AND age LIKE ? AND gender LIKE ?', "%#{location}%", "%#{breed.downcase}%", "%#{age}%", "%#{gender.downcase}%"])

psq的

将是

where('location ILIKE ? AND breed ILIKE ? AND age ILIKE ? AND gender ILIKE ?', "%#{location}%", "%#{breed.downcase}%", "%#{age}%", "%#{gender.downcase}%")

where('location @@ ? AND breed @@ ? AND age @@ ? AND gender @@ ?', location, breed.downcase, age, gender.downcase)

我建议观看此http://railscasts.com/episodes/343-full-text-search-in-postgresql?view=asciicast

并使用这个宝石。 https://github.com/activerecord-hackery/ransack

这样可以更轻松地获得您想要的结果。

答案 1 :(得分:1)

我认为问题是您对整数运行LIKE。没有您的架构的描述,但SQL错误似乎指向age是一个整数并且您无法对整数运行LIKE这一事实。

如果要对Integer运行LIKE,首先需要将其强制转换为VARCHAR(这可以在SQL中完成)。在PostgreSQL中,您可以在查询中调用以下命令:to_char(numeric, text)。它根据您作为 text 参数输入的格式从 numeric 返回一个String。