【问题标题】:Search method Ruby搜索方法 Ruby
【发布时间】:2018-12-15 14:51:33
【问题描述】:

我将此方法用于带有表单的 ruby​​ 搜索方法。

我认为,这段代码可以简化。你怎么看 ?

我有一个问题。当用户没有在表单中输入任何内容时,结果会显示数据库中的所有提示。

但是当用户结合两个搜索,例如一个关键字和一个国家,结果是所有有关键字的提示以及所有有相关国家的提示。除了我正在寻找的是要结合这两个标准。

搜索.rb

require 'pry'

class Search < ApplicationRecord

  def self.search(keywords, category_id,city,country)
    table_of_ids_country = []
    table_of_ids_city = []
    table_of_ids_title = []
    table_of_ids_cats = []
    two_searches_ids = []
    merged_table_of_tips_ids = []
    @results = []

    tips_by_country = Tip.where(["country like?",country]) if country.present?

    tips_by_city = Tip.where(["city like?",city]) if city.present?

    tips_by_keyword = Tip.where(["title LIKE?","%#{keywords}%"]) if keywords.present?

    tips_by_cat = Category.where(["id = :id",{id:category_id}]) if category_id.present?

    two_searches = Tip.where(["title LIKE?",keywords]) if keywords.present? && Category.where(["id = :id",{id:category_id}]) if category_id.present?

    if tips_by_country != nil
      tips_by_country.each do |tip|
        tip.id
        table_of_ids_country << tip.id
      end
    end

    if tips_by_city != nil
      tips_by_city.each do |tip|
        tip.id
        table_of_ids_city << tip.id
      end
    end

    if tips_by_keyword != nil
      tips_by_keyword.each do |tip|
        tip.id
        table_of_ids_title << tip.id
      end
    end

    if two_searches != nil
      two_searches.each do |tip|
        tip.id
        two_searches_ids << tip.id
      end
    end

    if tips_by_cat != nil
      Category.find(tips_by_cat[0].id).tips.each do |tip|
        table_of_ids_cats << tip.id
      end
    end

    merged_table_of_tips_ids = [table_of_ids_title, table_of_ids_cats,table_of_ids_city,table_of_ids_country,two_searches_ids].flatten

    merged_table_of_uniq_tips_ids = merged_table_of_tips_ids.uniq


    merged_table_of_uniq_tips_ids.each do |tip|
       result = Tip.find(tip)
       @results << result
       binding.pry
    end
    return @results
  end
end

搜索控制器

require 'pry'
class SearchesController < ApplicationController

  def new
    @search = Search.new
  end

  def create
    @search = Search.create(search_params)
    redirect_to @search
  end

  def show
    @search = Search.find(params[:id])
    @search = Search.search(@search.keywords, @search.category_id,@search.city,@search.country)
    #Permet d'envoyer les paramètres au model search et à les réutilisé dans la méthode self.search
  end

private

  def search_params
    params.require(:search).permit(:keywords,:category_id,:id,:city,:country)
  end
end

我的表格:

<%=form_for @search do |f| %>
          <div class="form-group">
            <%= f.label :keywords, "Mots-clés" %>
            <%= f.text_field :keywords, class: "form-control", placeholder: "plongée, randonnée, temple..." %>
          </div>
          <div class="form-group">
            <%= f.label :city, "Mots-clés" %>
            <%= f.text_field :city, class: "form-control", placeholder: "plongée, randonnée, temple..." %>
          </div>
          <div class="form-group">
            <%= f.label :country, "Mots-clés" %>
            <%= f.text_field :country, class: "form-control", placeholder: "plongée, randonnée, temple..." %>
          </div>
          <div class="form-group">
            <%= f.label :category_id, "Catégories" %><br>
            <%= f.collection_select :category_id, Category.all, :id, :name, :include_blank => true %>
          </div>
          <div class="form-group d-flex justify-content-center">
            <%= f.submit "Rechercher", class: "btn btn-primary" %>
          </div>
          <%end%>

【问题讨论】:

  • 您可以尝试将所有查询移至scope 以简化方法。

标签: ruby-on-rails search


【解决方案1】:
class Search < ApplicationRecord

  def self.search(keywords, category_id,city,country)
    ids = if keywords.present? && category_id.present?
            Tip.keywords(keywords).pluck(:id) & Category.category_id(category_id).pluck(:id)
          elsif [keywords, category_id, city, country].any?(&:present?)
            Tip.country(country)
              .city(city)
              .keywords(keywords)
              .pluck(:id)
          else
            []
          end

    Tip.find(ids.uniq)
  end
end

class Category < ApplicationRecofd
  scope :category_id, ->(category_id) {
    where(["id = :id",{id:category_id}])
  }
end

class Tip < ApplicationRecord
  scope :country, ->(country) {
    where("country like?",country) if country.present?
  }

  scope :city, ->(city) {
    where("city like?",city) if city.present?
  }

  scope :keyword, ->(keywords) {
    tips = tips.where("title LIKE?","%#{keywords}%") if keywords.present?
  }
end

还注意到我正在对类别 ID 进行联合,所以请记住

2.5.1 :002 > [1,2] && [2,3]
 => [2, 3] 
2.5.1 :003 > [1,2] & [2,3]
 => [2] 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-12
    • 2021-10-04
    • 2015-09-11
    • 2018-08-27
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    相关资源
    最近更新 更多