2011-07-31 20 views
11

Cơ sở dữ liệu phát triển của tôi là SQLite nhưng tôi triển khai ứng dụng của mình cho Heroku và họ đang sử dụng PostgreSQL.Tìm kiếm không hợp lệ trong Postgres với Rails

Bây giờ đôi khi tôi có hai kết quả khác nhau sắp ra nếu tôi thực hiện tìm kiếm vì PostgreSQL phân biệt chữ hoa chữ thường nhưng SQLite thì không.

Rails không nên tiêu chuẩn hóa những thứ này? Tôi nên sử dụng phương pháp nào để giải quyết điều đó?

Here is how to fix it with raw SQL

+1

Tôi khuyên bạn nên phát triển trên đầu trang của PostgreSQL nếu bạn đang triển khai cho Heroku. Không ORM nào sẽ bảo vệ bạn khỏi hành vi cụ thể của cơ sở dữ liệu. –

+1

Và tôi thích sử dụng SQLite cục bộ và Postgre khi vận chuyển, vì vậy tôi không gắn với một DB nào đó. cho riêng mình. –

Trả lời

41

Trường hợp tìm kiếm không nhạy cảm trong Postgres:

  • sử dụng ilike thay vì like (case-insensitive tương tự)
  • nếu bạn muốn sử dụng =, làm cho cả hai bên, hoặc trên hoặc dưới
+4

Cảm ơn bạn! Vấn đề với 'like' là tôi không biết cách kết nối chúng với toán tử' OR'. Là nó lưu để sử dụng điều này với mỗi db được hỗ trợ bởi đường ray? '' LOWER (tiêu đề) THÍCH LOWER ('% # {search_term}%') "' – antpaw

+1

cũng nó không phanh mã của tôi trong mysql, sqlite và pgsql vì vậy nó đủ tốt, cảm ơn! – antpaw

+0

sử dụng UPPER hoặc LOWER nếu bạn muốn chạy cùng một mã trên cả MYSQL và POSTGRES (mặc dù đó rõ ràng là không thực hành tốt nhất!) –

4

Khác DDL cách xử lý này là citext kiểu dữ liệu hoặc TEXT không phân biệt chữ hoa chữ thường.

4

Có nhiều điều tương đối phổ biến mà ActiveRecord không xử lý và đối sánh LIKE là một trong số đó. Đây là cách để đạt được điều này bằng cách sử dụng thẳng Arel thay thế.

Model.where(
    Model.arel_table[:title].matches("%#{search_term}%") 
) 

Bạn có thể cài đặt Arel-Helpers để làm điều này dễ dàng hơn một chút

Model.where(Model[:title].matches("%#{search_term}%")) 

tôi trước đây đề nghị Squeel cho điều này, nhưng tác giả ban đầu đã ngừng hỗ trợ nó và có vẻ không phải là một full- nhà phát triển thời gian duy trì nó. Và kể từ khi nó phát xung quanh với các API ActiveRecord riêng, nó cần sự chăm sóc liên tục.

+0

Giải pháp tuyệt vời, và Squeel là tuyệt vời, nhưng chỉ cần một đầu lên rằng đây là hành vi cụ thể Postgres. Nếu bạn đang tìm cách làm điều này cho các RDBMS khác, đầu ra có thể phân biệt chữ hoa chữ thường. – kgx

+0

@kgx thực tế ví dụ này sẽ hoạt động như dự định trong cả hai trường hợp. Như @antpaw đã nói ở trên, SQL LIKE 'LIKE' không phân biệt dạng chữ theo mặc định. Vì vậy, điều này sẽ sử dụng 'LIKE' trong SQLite và' ILIKE' trong PostgreSQL. –