Rails Postgres通过子字符串查找属性(多个单词)

时间:2017-08-24 06:02:43

标签: ruby-on-rails postgresql search

我试图找出如何使用LIKE语句在Postgres中实现以下功能:

数据:测试项目

以下搜索查询应返回测试项目: test est est project pro

目前我的projects.rb模型中的方法如下所示:

self.where('name LIKE ?', "%#{search}%")

(我当然会添加downcase)它当前获取:name属性值的第一个单词的任何变体但不是第二个单词的变体,因此搜索pro会没有回报。

projects.rb型号

  def self.search(search)
    if search
      scope :find_name, lambda { |search| where("name ILIKE :search", search: "%#{search.downcase}%") }
    else
      self.where(nil)
    end
  end


projects_controller.rb

def index                                
  @projects = Project.search(params[:search]
end  

index.html.erb
<p id="notice"><%= notice %></p>
<div class="projects-index">
  <div class="container-body text-center">
    <h1>Projects</h1>
    <%= form_tag projects_path, method: :get, id: "projects_search" do %>
      <p>
        <%= text_field_tag :search %>
      </p>
    <% end %>
  </div>
  <!-- CARDS -->
  <div class="row cards-section">
    <div id="projects">
      <%= render partial: 'projects' %>
    </div>
    <div class="col-3">
      <%= link_to new_project_path, class: "new-project text-center" do %>
        <div class="align vertical">
          <div class="align-flex center">
            <%= image_tag "add_project.png" %>
          </div>
          <p>New Project</p>
        </div>
      <% end %>
    </div>
  </div>
</div>

_projects.html.erb部分

<% @projects.each do |project| %>
  <div class="col-3">
    <div class="existing-card">
      <div class="top">
        <div class="ui icon left pointing dropdown button">
          <i class="ellipsis vertical icon"></i>
          <div class="menu">
            <div class="item">
              <%= link_to 'Edit', edit_project_path(project), class: "link" %>
            </div>
            <div class="item">
              <%= link_to 'Share', new_user_invitation_path, class: "link" %>
            </div>
            <div class="item">
              <%= link_to 'Delete', project_path(project), method: :delete, data: { confirm: 'Are you sure you want to delete this project?' }, class: "link" %>
            </div>
          </div>
        </div>
      </div>
      <div class="card-container align-flex center">
        <p><%= project.name %></p>
      </div>
    </div>
  </div>
<% end %>

2 个答案:

答案 0 :(得分:1)

self.where('name ILIKE %?', "%#{search}%")

答案 1 :(得分:1)

使用您的查询,您只需要将LIKE更改为ILIKE

self.where('name ILIKE ?', "%#{search.downcase}%")

要获得更多保存,我建议使用以下范围

scope :find_name, lambda { |search| where("name ILIKE :search", search: "%#{search.downcase}%") }

为您的案例编辑

不要在范围内使用范围,有关范围的更多信息,请参阅link 对于您的情况,您可以按照以下方式更改索引

def index                                
  @projects = Project.find_name(params[:search]
end 

并更改此

  def self.search(search)
    if search
      scope :find_name, lambda { |search| where("name ILIKE :search", search: "%#{search.downcase}%") }
    else
      self.where(nil)
    end
  end

到这个

scope :find_name, lambda { |search| where("name ILIKE :search", search: "%#{search.downcase}%") }