2015-06-03 11 views
14

Tôi đang làm việc với Rails 4.2 và Postgres 9.4 để thử kiểu dữ liệu JSONB mới. Một trong các cột JSONB trong cơ sở dữ liệu của tôi chứa một mảng và tôi muốn có thể truy vấn các bản ghi trong đó mảng này chứa một giá trị nhất định. Tôi đã tìm ra cách để làm điều này bằng cách sử dụng JSONB "dấu hỏi" mới ("chứa") điều hành, như ghi nhận ở đây: http://www.postgresql.org/docs/9.4/static/functions-json.htmlLàm thế nào để thoát khỏi? (toán tử dấu hỏi) để truy vấn loại JSONB Postgresql trong Rails

Vì vậy, trong SQL liệu tôi có thể có được điều này để làm việc như trong ví dụ này:

SELECT * FROM people WHERE roles ? '32486d83-4a38-42ba-afdb-f77ca40ea1fc'; 

Nhưng tôi không thể thấy bất kỳ cách nào để thực hiện truy vấn này từ bên trong Rails qua ActiveRecord. Tôi đã thử làm một truy vấn liệu bằng cách sử dụng "ở đâu" phương pháp, như sau:

Person.where("roles ? ?", "32486d83-4a38-42ba-afdb-f77ca40ea1fc") 

Nhưng kể từ khi dấu hỏi là một nhân vật đặc biệt sử dụng để thay thế các thông số, tôi nhận được lỗi này:

ActiveRecord::PreparedStatementInvalid: wrong number of bind variables (1 for 2) in: roles ? ?

Tôi đoán tôi cần một cách để thoát khỏi "?" nhân vật kể từ khi tôi muốn nó đi qua nghĩa đen. Tôi đã thử \? và ?? không may mắn. Bất kỳ trợ giúp nào được đánh giá cao!

+0

thử này ' Person.where ("vai trò? (?)", "32486d83-4a38-42ba-afdb-f77ca40ea1fc") ' –

+0

hoặc' Person.where ("vai trò?: Tên", tên: "32486d83-4a38-42ba-afdb- f77ca40ea1fc ")' –

+0

Tính năng này có phù hợp với bạn không ??? –

Trả lời

19

Bạn nên gọi này như sau:

Person.where("roles ? :name", name: "32486d83-4a38-42ba-afdb-f77ca40ea1fc") 
4

Một cách giải quyết. Chạy truy vấn này để tìm hiểu những gì có chức năng bản đồ hành của bạn để:

SELECT 
    oprname, 
    oprcode || '(' || format_type(oprleft, NULL::integer) || ', ' 
       || format_type(oprright, NULL::integer) || ')' AS function 
FROM pg_operator 
WHERE oprname = '?'; 

Nó mang lại

oprname function 
?  jsonb_exists(jsonb, text) 
?  exist(hstore, text) 

Bây giờ sử dụng chức năng thay vì các nhà điều hành trong truy vấn của bạn:

Person.where("jsonb_exists(roles, ?)", "32486d83-4a38-42ba-afdb-f77ca40ea1fc") 
Các vấn đề liên quan