简体   繁体   English

Ruby on rails - 添加 select 标签来搜索不同的字段

[英]Ruby on rails - adding a select tag to search different fields

I'm working on a search feature for an app, I have aa basic search working, however, I need to be able to have a select field to select what the user searches.我正在开发一个应用程序的搜索功能,我有一个基本的搜索工作,但是,我需要能够有一个 select 字段到 select 用户搜索的内容。

ie If I have a select tag with the following:即,如果我有一个 select 标签,其内容如下:

Name, Currency, Company name名称、货币、公司名称

I need to be able to select the dropdown option and then enter my search term, here is what my form looks like我需要能够 select 下拉选项,然后输入我的搜索词,这是我的表单的样子在此处输入图像描述

My form looks like this我的表格看起来像这样

<%= form_tag contacts_path, method: :get do %>
  <div class='l-inline-row-block'>
    <div class='l-inline-col'>
      <%= select_tag(:qs, options_for_select(['name', 'customers', 'suppliers', 'tags'], selected: params[:qs])) %>
    </div>

    <div class='l-inline-col'>
      <%= search_field_tag :search, params[:search] %>
    </div>

    <div class='l-inline-col'>
      <%= submit_tag submit_text, { class: 'no_print' } %>
    </div>
  </div>
<% end %>

I have the following in the controller index method我在 controller 索引方法中有以下内容

 @contacts = Contact.search(params[:search])

and the following in the model以及 model 中的以下内容

def self.search(search)
  if search
    contacts = Contact.order(:id)
    contacts = contacts.where("name like ?", "%#{search}%") if search.present?
    contacts
  else
    contacts = Contact.all
  end
end

I have looked into https://railscasts.com/episodes/111-advanced-search-form-revised but I don't need a separate search page I need all the searching to happen on the index page.我已经查看了https://railscasts.com/episodes/111-advanced-search-form-revised但我不需要单独的搜索页面我需要在索引页面上进行所有搜索。

Any help would be great.任何帮助都会很棒。

Update更新

I've use the following solution from @max (thank you), however, running into some other issues:我使用了@max 的以下解决方案(谢谢),但是遇到了其他一些问题:

Here is the db structure:这是数据库结构:

  create_table "contacts", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.integer  "customer_account_id"
    t.integer  "supplier_account_id"
    t.string   "name"
    t.string   "salutation"
    t.string   "title"
    t.string   "phone"
    t.string   "mobile"
    t.string   "business_email"
    t.string   "private_email"
    t.date     "date_of_birth"
    t.string   "spouse"
    t.string   "address_1"
    t.string   "address_2"
    t.string   "address_3"
    t.string   "address_4"
    t.string   "postcode"
    t.text     "other_information",   limit: 65535
    t.integer  "created_by"
    t.integer  "updated_by"
    t.string   "contact_type"
    t.integer  "assigned_to"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "company_name"
    t.string   "web_address"
    t.string   "second_phone"
    t.integer  "prospect_strength"
    t.boolean  "obsolete"
    t.string   "url"
    t.index ["obsolete"], name: "index_contacts_on_obsolete", using: :btree
  end

Each contacts record has a contact_type so not sure if we could search off that but need both customer and supplier options.每个联系人记录都有一个contact_type ,所以不确定我们是否可以搜索,但需要客户和供应商选项。

在此处输入图像描述

were using acts_as_taggable for the tags which need to be searchable.对需要搜索的标签使用acts_as_taggable

Here is the current method that the previous search uses if this helps如果有帮助,这是先前搜索使用的当前方法

def quick_search_fields
  @quick_search_fields = [
    {
      col_name: 'name',
      title: 'name',
      column_names: ['contacts.name']
    },
    {
      col_name: 'customer_name',
      title: 'customer',
      search_tables: [:customer],
      column_names: ['accounts.name']
    },
    {
      col_name: 'supplier_name',
      title: 'supplier',
      search_tables: [:supplier],
      column_names: ['accounts.name']
    },
    {
      col_name: 'tags',
      title: 'tags',
      tags: true,
      tagged: Contact
    }
  ]
end

Here is my select_tag <%= select_tag(:qs, options_for_select(['name', 'customers', 'suppliers', 'tag_list'], selected: params[:qs])) %> + the changes in max's solution.这是我的select_tag <%= select_tag(:qs, options_for_select(['name', 'customers', 'suppliers', 'tag_list'], selected: params[:qs])) %> + max 解决方案的变化。 However, here's the error that I'm getting when searching suppliers, customers and tags.但是,这是我在搜索供应商、客户和标签时遇到的错误。

Mysql2::Error: Unknown column 'contacts.customers' in 'where clause': SELECT  `contacts`.* FROM `contacts` WHERE (`contacts`.`suppliers` LIKE '%john%') ORDER BY id asc LIMIT 20 OFFSET 0

You need to increase the arity of your search method to 2 and construct a LIKE query with a dynamic column name:您需要将搜索方法的数量增加到 2 并使用动态列名构造一个 LIKE 查询:

class Contact < ApplicationRecord
  # Prevents sql injections
  SEARCHABLE_FIELDS = ['name', 'customers', 'suppliers', 'tags']

  def self.search(field, query)
    if field.present? && query.present? && SEARCHABLE_FIELDS.include?(field)
      # WHERE contacts.field LIKE '%?%'
      where(arel_attribute(field).matches("%#{query}%"))
    else
      all
    end
  end
end
@contacts = Contact.search(params[:qs], params[:search])

If you want to vary the logic performed by the search depending on the field I would really suggest you extract this functionality out of the model into a seperate object or look at gems such as Ransack.如果您想根据字段更改搜索执行的逻辑,我真的建议您将此功能从 model 提取到单独的 object 或查看诸如 Ransack 之类的宝石。

See:看:

If I understood what you want to achieve, I think you could do it all in the controller like this:如果我了解您想要实现的目标,我认为您可以像这样在 controller 中完成所有操作:

def index
  if params[:search].present?
    case params[:qs]
    when 'name'
      result = 'your query for name'
    when 'customers'
      result = 'your query for customers'
    when 'suppliers'
      result = 'your query for suppliers'
    else
      result = 'your query for tags'
    end
    result
   else
     a default query if no search
   end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM