복붙노트

[RUBY-ON-RAILS] 일반 루비 sqlite3를 "LIKE"또는 PostgreSQL을 "ILIKE"에 대한 해결책?

RUBY-ON-RAILS

일반 루비 sqlite3를 "LIKE"또는 PostgreSQL을 "ILIKE"에 대한 해결책?

나는 배치를위한 개발과 PostgreSQL을위한 sqlite3를 사용하고 있습니다. 그러나, 나는 다음과 같은 문제에 직면하고있다 :

내 간단한 sqlite3를을 사용하여 검색 :

def self.search(search)
    if search
      find(:all, :conditions => ["style LIKE ? OR construction LIKE ?", "%#{search}%", "%#{search}%"])
    else
      find(:all)
    end
end

그러나, PostgreSQL을 작동하지 않습니다, 나는 ILIKE이 문제를 해결하기 위해 LIKE를 교체해야합니다 :

def self.search(search)
    if search
      find(:all, :conditions => ["style ILIKE ? OR construction ILIKE ?", "%#{search}%", "%#{search}%"])
    else
      find(:all)
    end
end

데이터베이스를 통해 이러한 검색을 할 수있는 '루비 방법은 "이 있습니까?

편집 - 당신의 응답에 따라 나는 내가 그에 대한 일반적인 루비 솔루션을 찾을 생각하지 않는다.

나는 레일 튜토리얼에 루비 따랐다 : 예에 의한 레일 알아보기 - 최종 Gemfile이 두 데이터베이스를 보여줍니다 마이클 하틀, ... 음, 실망에 의해를 ...

해결법

  1. ==============================

    1.문제의 뿌리는 여기에있다 :

    문제의 뿌리는 여기에있다 :

    그건 좋은 생각 ™입니다. 당신은 호환성 문제로 계속 실행한다 - 또는 더 나쁜 : 손상이 완료 될 때까지 몇 가지를 실현하지. 무의미 ​​문제 개발 및 생산에 직접 저장 같은 RDBMS (PostgreSQL을)를 사용합니다.

    당신이 당신의 불행한 설치와 함께 붙어있는 동안, 간단한 수정이 있습니다 :

    lower(style) LIKE lower(?)
    

    모두 두 플랫폼 모두에서 작동합니다.

  2. ==============================

    2.나는 Arel이 문제를 해결하는 가장 좋은 방법이라고 생각합니다. 그것은 활성 레코드 레일에 의해 사용 및 데이터베이스 독립적이다. 코드는 sqlite3를하거나 상황에 맞게 보인다 포스트 그레스에서 동일하게 작동합니다. 일치하는 방법을 사용하면 자동으로 포스트 그레스 환경에서 ILIKE로 전환됩니다. 예:

    나는 Arel이 문제를 해결하는 가장 좋은 방법이라고 생각합니다. 그것은 활성 레코드 레일에 의해 사용 및 데이터베이스 독립적이다. 코드는 sqlite3를하거나 상황에 맞게 보인다 포스트 그레스에서 동일하게 작동합니다. 일치하는 방법을 사용하면 자동으로 포스트 그레스 환경에서 ILIKE로 전환됩니다. 예:

    users=User.arel_table
    User.where(users[:style].matches("%#{search}%").or(users[:construction].matches("%#{search}%")))
    

    당신은 GitHub의에서 더 많은 정보를 얻을 수 있습니다 : https://github.com/rails/arel/

  3. ==============================

    3.아니, 데이터베이스를 검색 할 "루비 방법"이 없습니다 - 루비 레일 (특히 액티브)에 액티브가 지원하는 RDB에에 CRUD 작업을 수행하기위한 헬퍼 메소드를 포함하지만 다음의 예제를 LIKE를 사용하여 검색하는 것이 훨씬 더 나은 방법이 없다 당신은 제공했다.

    아니, 데이터베이스를 검색 할 "루비 방법"이 없습니다 - 루비 레일 (특히 액티브)에 액티브가 지원하는 RDB에에 CRUD 작업을 수행하기위한 헬퍼 메소드를 포함하지만 다음의 예제를 LIKE를 사용하여 검색하는 것이 훨씬 더 나은 방법이 없다 당신은 제공했다.

    이 토론에 관련된 레일 문서의 섹션은 액티브 :: FinderMethods 될 것이다.

    대신 발견을하는 보조 노트로서, (모든) 당신은 모든 것을 할 수 있습니다.

    레일즈 문서는 즉 문 같은 일을 위해 사용과 같은 구문을 사용합니다 :

    Person.exists?(['name LIKE ?', "%#{query}%"])
    

    위의 방법을 사용하여 완벽하게 안전합니다.

    를 Where 문자열 착취에 개방 PARAMS에서 (즉, 간단한 아포스트로피 데이터베이스 잎 어떤 위생없이 데이터베이스 쿼리에 직접 전달되기 때문에 그 이유는 같은 문장 아래에 왜 안전은 [: FIRST_NAME] 엉망 전체 쿼리 최대 수 취약 데이터베이스를 떠나 - 특히 SQL 주입). 위의 예에서, 액티브는 쿼리에 전달되는 매개 변수를 살균 할 수 있습니다.

    Client.where("first_name LIKE '%#{params[:first_name]}%'")
    
  4. ==============================

    4.불행하게도 나는이에게 좋은 솔루션을 찾을 거라고 생각하지 않습니다. 대신, 당신이 사용할 수있는 유일한 구문 : 조건은 어디에요 절을 사용하는 것입니다 :

    불행하게도 나는이에게 좋은 솔루션을 찾을 거라고 생각하지 않습니다. 대신, 당신이 사용할 수있는 유일한 구문 : 조건은 어디에요 절을 사용하는 것입니다 :

    where(["style ILIKE ? OR construction ILIKE ?", "%#{search}%", "%#{search}%"])
    

    당신은 아마 깨달았다 불행하게도,이 대체 구문은 동일한 문제로 실행됩니다. 이 프로덕션 환경에서 실질적으로 다른 개발 환경을 가지고에서 발생하는거야 불만의 하나에 불과 - SQLite는과 포스트그레스 SQL과 다른 매우 중요한 차이점도 있습니다. 난 그냥 개발 시스템에 포스트 그레스를 설치하고 그 사용을 권장합니다. 그것은 쉽게 많은 개발 만들고, 코드를 많이 청소기 만들 수 있습니다.

  5. ==============================

    5.https://github.com/ernie/squeel/ : 그것은 생산 및 개발에 서로 다른 데이터베이스를 사용하는 것이 좋습니다는 아니지만, 그것은 여전히 ​​squeel 보석을 사용하는 좋은 사례입니다

    https://github.com/ernie/squeel/ : 그것은 생산 및 개발에 서로 다른 데이터베이스를 사용하는 것이 좋습니다는 아니지만, 그것은 여전히 ​​squeel 보석을 사용하는 좋은 사례입니다

    그것으로, 당신은 쉽고 틀림없이 매우 깨끗하고 원시 SQL보다 더 읽을 수있는 DSL으로 쿼리를 작성 할 수 있으며 RDBMS를 사용하는 보석은 SQL의 특정에의 변환을 처리합니다.

    http://railscasts.com/episodes/354-squeel : 라이언 베이츠 그것에 대해 좋은 비디오가

  6. ==============================

    6.여기 내 솔루션되면 저도 같은 문제에 직면했다 :

    여기 내 솔루션되면 저도 같은 문제에 직면했다 :

    나는 그것이 가능한 각 데이터베이스의 기능을 사용할 수 있도록 약간의 lib 디렉토리를 썼다 :

    class AdapterSpecific
    
      class << self
        def like_case_insensitive
          case ActiveRecord::Base.connection.adapter_name
          when 'PostgreSQL'
            'ILIKE'
          else
            'LIKE'
          end
        end    
    
        def random
          #something
        end
      end
    

    모델에이 기능을 사용하려면

    def self.search(search)
        if search
          find(:all, :conditions => ["style #{AdapterSpecific.like_case_insensitive} :query OR construction #{AdapterSpecific.like_case_insensitive} :query", {:query => "%#{search}%"}])
        else
          find(:all)
        end
    end
    

    기록 된 이후이 여러 가지 이유로 (다른 답변을 참조) 훨씬 더 나은 설정이기 때문에, 나는 포스트 그레스에 배포 데이터베이스를 마이그레이션.

    당신은 또한 당신의 텍스트, 훨씬 더 효율적으로 검색 할 더 많은 사용자 정의를 필요로하는 경우 기본 구현 또는 pg_search에 대한 texticle를 참조 할 것 포스트 그레스에 대한 전체 텍스트 검색을 사용하여 생각할 수 있습니다.

  7. ==============================

    7.LIKE를 사용하여 검색하면 데이터베이스에 고통 스러울 수 있습니다. 물론 그것은 매우 금지 비용을 수있는 인덱스를 사용 실 거예요.

    LIKE를 사용하여 검색하면 데이터베이스에 고통 스러울 수 있습니다. 물론 그것은 매우 금지 비용을 수있는 인덱스를 사용 실 거예요.

    더 긴 대답은 : 나는 (죽겠다 sqlite3를) 개발에 포스트 그레스를 사용하여 다음 포스트 그레스 'tsvector 유형을 통해 전체 텍스트 모든 검색 필드 스타일에 인덱스 구성을 갖는 것이 좋습니다.

    인덱스를 사용하여 포스트 그레스에서 전체 텍스트 검색은 매우 빠르다.

  8. from https://stackoverflow.com/questions/11249059/generic-ruby-solution-for-sqlite3-like-or-postgresql-ilike by cc-by-sa and MIT license