Rails搜索多个查询无法正常工作

时间:2016-03-05 00:52:53

标签: ruby-on-rails forms

我知道我的代码很笨重,但我想在我的GUEST数据库中为不同的列创建一个包含多个文本框的表单。表单不起作用,我的所有访客条目仍然列出(列表不会被搜索范围缩小)。如果有人能指出我正确的方向,那将是非常棒的。另外guest.rb代码怎么能更简洁?

控制器:

def index
    @guests = Guest.all
    if params[:search_first_name]
      @guests = Guest.search_first_name(params[:search_first_name])
    end
    if params[:search_last_name]
      @guests = Guest.search_last_name(params[:search_last_name])
    end
    if params[:search_email]
      @guests = Guest.search_email(params[:search_email])
    end
    if params[:search_phone]
      @guests = Guest.search_phone(params[:search_phone])
    end
  end

guest.rb

def self.search_first_name(query)
        # where(:email, query) -> This would return an exact match of the query
        where("first_name like ?", "%#{query}%") 
      end

      def self.search_last_name(query)
        # where(:email, query) -> This would return an exact match of the query
        where("last_name like ?", "%#{query}%") 
      end

      def self.search_email(query)
        # where(:email, query) -> This would return an exact match of the query
        where("email like ?", "%#{query}%") 
      end

      def self.search_phone(query)
        # where(:email, query) -> This would return an exact match of the query
        where("phone like ?", "%#{query}%") 
      end

的index.html:

<%= form_tag(guests_path, :method => "get", class: "navbar-form", id: "search-form") do %>
          <div class="input-append col-sm-10">
            <div class="row">
            <div class="col-sm-4">
              <p><%= text_field_tag :search_first_name, params[:search_first_name], placeholder: "First Name", style: "width:100%;" %></p>
              <p><%= text_field_tag :search_last_name, params[:search_last_name], placeholder: "Last Name", style: "width:100%;" %></p>
            </div>
            <div class="col-sm-4">
              <p><%= text_field_tag :search_email, params[:search_email], placeholder: "Email Address", style: "width:100%;" %></p>
              <p><%= text_field_tag :search_phone, params[:search_phone], placeholder: "Phone Number", style: "width:100%;" %></p>
            </div>
            <div class="col-sm-4">

            </div>
              <%= submit_tag 'Search Guests' %>
          </div>
        </div>
      <% end %>

<table class="table table-hover col-sm-12">
  <thead>
    <tr>
      <th>Guest ID</th>
      <th>Guest Name</th>
      <th>Email</th>
      <th>Phone</th>
      <th></th>
    </tr>
  </thead>

  <tbody>
    <% @guests.each do |guest| %>
      <tr>
        <td>G-00<%= guest.id %></td>
        <td><%= guest.first_name %> <%= guest.last_name %></td>
        <td><%= guest.email %></td>
        <td><%= guest.phone %></td>
        <td style="text-align:right;"><%= link_to 'View Guest Profile', guest, :class => "btn btn-sm btn-success" %> <%= link_to 'Edit', edit_guest_path(guest), :class => "btn btn-sm btn-default" %> <%= link_to 'Destroy', guest, method: :delete, data: { confirm: 'Are you sure?' }, :class => "btn btn-sm btn-danger" %></td>
      </tr>
    <% end %>
  </tbody>
</table>

3 个答案:

答案 0 :(得分:3)

问题来了,因为没有值的param将等于"",但在Ruby中仍然是true,所以基本上如果你的search_phone是空的那么你会看到所有结果,因为if params[:search_phone]将为true,因此将运行块,并且运行的最终代码将等同于:

@guests = Guest.where( "phone like '%%'" )

这只是两个通配符,因此会返回所有结果。其他人已经提到将条件更改为使用.present?,因此如果它是空白则不会运行。

您还询问了重构代码的问题,我会这样写:

控制器

def index
  @guests = Guest.search_or_all params
end

模型

def self.search_or_all params={}
  query = %i[first_name last_name email phone].map do |k|
    kk = "search_#{k}"
    sanitize_sql ["#{k} LIKE '%s'", "%#{params[kk]}%"] if params[kk]
  end.compact.join " OR "
  where query
end

答案 1 :(得分:2)

没有深入到代码重构。尝试将params[:field_name].present?添加到所有if语句中。

答案 2 :(得分:-1)

你应该把"^#{query}"作为正则表达式 这样,您的Guest.rb文件将如下所示

Guest.rb

  def self.search_first_name(query)
    # where(:email, query) -> This would return an exact match of the query
    where("first_name like ?", "^#{query}") 
  end

  def self.search_last_name(query)
    # where(:email, query) -> This would return an exact match of the query
    where("last_name like ?", "^#{query}") 
  end

  def self.search_email(query)
    # where(:email, query) -> This would return an exact match of the query
    where("email like ?", "") 
  end

  def self.search_phone(query)
    # where(:email, query) -> This would return an exact match of the query
    where("phone like ?", "%#{query}%") 
  end