0

ユーザーがさまざまなフィールドで検索できる検索機能を構築しようとしています。ドロップダウンメニューを使用して、クライアント、業界、テクノロジー。ユーザーが一度に複数のテクノロジーを検索できるようにするまで、検索機能は機能していました。

これが私のモデルです:

class Project < ActiveRecord::Base
  attr_accessible :tech2, :tech3, :tech4, :tech5, :edited_first_name, :edited_last_name, :first_name, :last_name, :business_div, :client, :customer_benifits, :edited_date, :end_date, :entry_date, :industry, :keywords, :lessons_learned, :project_name, :project_owner, :role, :start_date, :status, :summary, :tech



def self.search(search_client, search_industry, search_role, search_tech, search_tech2, search_tech3, search_tech4, search_tech5 , search_business_div, search_project_owner,  search_status, search_start_date_dd, search_start_date_A, search_start_date_B,  search_keywords) 
  return scoped unless search_client.present? || search_industry.present? || search_role.present? || search_tech.present? || search_tech2.present? || search_tech3.present? || search_tech4.present? || search_tech5.present? || search_business_div.present? || search_project_owner.present? || search_status.present? ||  search_keywords.present?


where(['client LIKE ? AND industry LIKE ? AND role LIKE ? AND (tech LIKE ? OR ? OR ? OR ? OR ? ) AND business_div LIKE ? AND project_owner LIKE ? AND status LIKE ? AND keywords LIKE ?', 
      "%#{search_client}%", "%#{search_industry}%" , "%#{search_role}%" , "%#{search_tech}%"  , "%#{search_tech2}%" , "%#{search_tech3}%"  , "%#{search_tech4}%" , "%#{search_tech5}%" ,"%#{search_business_div}%" , 
      "%#{search_project_owner}%"  , "%#{search_status}%", 
       "%#{search_keywords}%"
    ])



end


def self.paginated_for_index(projects_per_page, current_page)
    paginate(:per_page => projects_per_page, :page => current_page)
  end

end

そして、これが私のプロジェクトコントローラーでの私の検索アクションです:

def search


@search = params[:client], params[:industry], params[:role], params[:tech], params[:tech2],params[:tech3],params[:tech4],params[:tech5], params[:business_div], params[:project_owner], params[:status], params[:keywords]

@project_search = Project.search(*@search).order(sort_column + ' ' + sort_direction).paginated_for_index(per_page, page)

@search_performed = !@search.reject! { |c| c.blank? }.empty? 

   @project = Project.new(params[:project])


respond_to do |format|
      format.html # search.html.erb
      format.json { render :json => @project }
    end

end

テクノロジーを検索しようとすると、次のエラーが表示されます。

ActiveRecord::StatementInvalid in Projects#search

    PG::Error: ERROR:  invalid input syntax for type boolean: "%%"
LINE 1: ...ND role LIKE '%%' AND (tech LIKE '%Telephony%' OR '%%' OR '%...
                                                             ^
: SELECT COUNT(*) FROM "projects"  WHERE (client LIKE '%%' AND industry LIKE '%%' AND role LIKE '%%' AND (tech LIKE '%Telephony%' OR '%%' OR '%%' OR '%%' OR '%%' ) AND business_div LIKE '%%' AND project_owner LIKE '%%' AND status LIKE '%%' AND keywords LIKE '%%')

Extracted source (around line #169):

166: 
167: <% if @project_search.total_entries > 0 %>
168: <% if @search_performed %>
169: 
170: <style>
171: CSS3 Code
172: 

null を返す他のテクノロジのドロップダウン メニューと関係があると思います。うまくいけば、誰かが問題を見ることができます。前もって感謝します。

アップデート:

def self.like(text); "%#{text}%"; end

  def self.search(search_client, search_industry, search_role, search_tech, search_tech2, search_tech3, search_tech4, search_tech5, search_business_div, search_project_owner,  search_status, search_start_date_dd, search_start_date_A, search_start_date_B,  search_keywords)
    # start with a scoped query, to apply more scopes on it afterwards
    _projects = Project.scoped 
    # then, for each of the parameters, apply the scope only if present
    if search_client.present?
      _projects = _projects.where ['client LIKE ?', like(search_client)] 
    end
    if search_industry.present?
      _projects = _projects.where ['industry LIKE ?', like(search_industry)]
    end
    if search_role.present?
      _projects = _projects.where ['role LIKE ?', like(search_role)]
    end

    # here lies the problem. you search in the 'tech' column, but you seem to want to search in many columns...
    search_techs = [search_tech, search_tech2, 
          search_tech3, search_tech4, 
          search_tech5].select(&:present?).compact
    if search_techs.present?
      sql = (['tech LIKE ?'] * search_techs.size).join(" OR ")
      args = search_techs.collect {|t| like(t)}
      _projects = _projects.where [sql, *args]
    end
    if search_business_div.present?
      _projects = _projects.where ['business_div LIKE ?', like(search_business_div)]
    end
    if search_project_owner.present?
      _projects = _projects.where ['project_owner LIKE ?', like(search_project_owner)]
    end

     if search_status.present?
      _projects = _projects.where ['status LIKE ?', like(search_status)]
    end



todays_date = DateTime.now.to_date

if !search_start_date_A.blank? or !search_start_date_B.blank?
    search_start_date_A = Date.parse(search_start_date_A).strftime("%Y-%m-%d")
    search_start_date_B = Date.parse(search_start_date_B).strftime("%Y-%m-%d")
    todays_date = nil
    search_start_date_dd = nil

    end

if search_start_date_dd.blank?
    todays_date = nil
end

        if search_start_date_dd.blank?

      _projects = _projects.where [' DATE(start_date) BETWEEN ? AND ?', search_start_date_A, search_start_date_B]
    end


        if search_start_date_A.blank? or search_start_date_B.blank?
      _projects = _projects.where ['DATE(start_date) BETWEEN ? AND ?', search_start_date_dd, todays_date]
    end




    if search_keywords.present?
      _projects = _projects.where ['keywords LIKE ?', like(search_keywords)]
    end
    # now you have applied only the present scopes. return the result, and watch 
    # the query as it executes.
    _projects
  end
4

2 に答える 2

2

SQL構文によると、クエリは無効です。

tech LIKE '%1%' OR '%2%' OR '%3%'

代わりにこれを試してください:

tech LIKE '%1%' OR tech LIKE '%2%' OR tech LIKE '%3%'
于 2012-10-01T14:13:10.463 に答える
1

あなたの検索方法はもっと良く書くことができます。それは問題を見つけるのに役立ちます (基本的に役に立たない LIKE に依存します。

しかし、あなたはデータベースを彼の仕事ではないものにしています。非常に多くの LIKE は、RDBMS の墓石です。solr のような全文検索ツールを使用すると、API の方が簡単で、はるかにうまく機能します。

ここには、search必要な場合にのみすべての LIKE が追加される、ほぼ同等のメソッドがあります。

class Project < ActiveRecord::Base

  def self.like(text); "%#{text}%"; end

  def self.search(search_client, search_industry, search_role, 
                  search_tech, search_tech2, search_tech3, search_tech4, 
                  search_tech5, search_business_div, search_project_owner,
                  search_status, search_start_date_dd, search_start_date_A, 
                  search_start_date_B,  search_keywords)
    # start with a scoped query, to apply more scopes on it afterwards
    _projects = Project.scoped 
    # then, for each of the parameters, apply the scope only if present
    if search_client.present?
      _projects = _projects.where ['client LIKE ?', like(search_client)] 
    end
    if search_industry.present?
      _projects = _projects.where ['industry LIKE ?', like(search_industry)]
    end
    if search_role.present?
      _projects = _projects.where ['role LIKE ?', like(search_role)]
    end
    if search_industry.present?
      _projects = _projects.where ['industry LIKE ?', like(search_industry)]
    end
    # here lies the problem. you search in the 'tech' column, but you seem to want to search in many columns...
    search_techs = [search_tech, search_tech2, 
          search_tech3, search_tech4, 
          search_tech5].select(&:present?).compact
    if search_techs.present?
      sql = (['tech LIKE ?'] * search_techs.size).join(" OR ")
      args = search_techs.collect {|t| like(t)}
      _projects = _projects.where [sql, *args]
    end
    if search_business_div.present?
      _projects = _projects.where ['business_div LIKE ?', like(search_business_div)]
    end
    if search_project_owner.present?
      _projects = _projects.where ['project_owner LIKE ?', like(search_project_owner)]
    end
    if search_status.present?
      _projects = _projects.where ['status LIKE ?', like(search_status)]
    end
    if search_keywords.present?
      _projects = _projects.where ['keywords LIKE ?', like(search_keywords)]
    end
    # now you have applied only the present scopes. return the result, and watch 
    # the query as it executes.
    _projects
  end
于 2012-10-01T16:32:52.333 に答える