Bạn có thể làm nhiều hơn so với so sánh vào một ngày trong tìm kiếm Rails 3 không?


125

Tôi có tìm kiếm này trong Rails 3:

Note.where(:user_id => current_user.id, :notetype => p[:note_type], :date => p[:date]).order('date ASC, created_at ASC')

Nhưng tôi cần :date => p[:date]điều kiện để tương đương :date > p[:date]. Tôi có thể làm cái này như thế nào? Cảm ơn vì đã đọc.

Câu trả lời:


226
Note.
  where(:user_id => current_user.id, :notetype => p[:note_type]).
  where("date > ?", p[:date]).
  order('date ASC, created_at ASC')

hoặc bạn cũng có thể chuyển đổi mọi thứ thành ký hiệu SQL

Note.
  where("user_id = ? AND notetype = ? AND date > ?", current_user.id, p[:note_type], p[:date]).
  order('date ASC, created_at ASC')

2
có an toàn không ý tôi là nếu p [: date] xuất phát từ đầu vào của người dùng, nó có thể gây ra lỗi SQL không?
MhdSyrwan

7
Nó an toàn vì where(). Sử dụng where()tự động thoát khỏi đầu vào.
Simone Carletti

34
Nhận xét của Simone không hoàn toàn đúng; where()tự động thoát khỏi đầu vào khi nó được sử dụng ở định dạng hiển thị ở trên với dấu chấm hỏi thay cho các biến, với chúng được liệt kê sau đó trong lệnh gọi hàm. Không an toàn khi sử dụng theo cách này:Note.where("date > #{p[:date]}")
bdx

4
Cũng đáng lưu ý, sử dụng where("user_id = ?",current_user.id)là rủi ro hơn where(user_id: current_user.id)trong trường hợp bạn hợp nhất các mô hình mà cả hai đều có một user_idtrường. Sử dụng ký hiệu SQL thô có nghĩa là bạn cần bao gồm chính bảng làm rõ, ví dụ : where("notes.user_id = ?",current_user.id).
DreadPirateShawn

1
Bạn nên cẩn thận với điều này, bởi vì múi giờ. Khi bạn sử dụng vị trí có "" Rails đi trực tiếp vào cơ sở dữ liệu và trong cơ sở dữ liệu, ngày được lưu trong UTC, nhưng bạn nên ở trong UTC + 5 chẳng hạn, và điều này sẽ không chính xác. Vì vậy, hãy đảm bảo chuyển đổi p [ngày] sang UTC hiện tại của bạn trước khi thực hiện
Paulo Tarud

70

Nếu bạn gặp sự cố trong đó tên cột không rõ ràng, bạn có thể thực hiện:

date_field = Note.arel_table[:date]
Note.where(user_id: current_user.id, notetype: p[:note_type]).
     where(date_field.gt(p[:date])).
     order(date_field.asc(), Note.arel_table[:created_at].asc())

2
Vì một số lý do, tôi đã gặp lỗi với một cột không được tìm thấy bằng phương thức "where" của Simone trên máy chủ PostgreQuery nhưng nó hoạt động trong SQLite. Phương pháp của bạn làm việc trên cả hai.
plackemacher

2

Bạn có thể thử sử dụng:

where(date: p[:date]..Float::INFINITY)

tương đương trong sql

WHERE (`date` >= p[:date])

Kết quả là:

Note.where(user_id: current_user.id, notetype: p[:note_type], date: p[:date]..Float::INFINITY).order(:fecha, :created_at)

Và tôi cũng đã thay đổi

order('date ASC, created_at ASC')

Dành cho

order(:fecha, :created_at)

0

Rails 6.1 đã thêm một 'cú pháp' mới cho các toán tử so sánh trong các wheređiều kiện, ví dụ:

Post.where('id >': 9)
Post.where('id >=': 9)
Post.where('id <': 3)
Post.where('id <=': 3)

Vì vậy, truy vấn của bạn có thể được viết lại như sau:

Note
  .where(user_id: current_user.id, notetype: p[:note_type], 'date >', p[:date])
  .order(date: :asc, created_at: :asc)

Đây là một liên kết đến PR nơi bạn có thể tìm thấy nhiều ví dụ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.