Rails 3 검색에서 날짜 비교보다 더 많은 것을 할 수 있습니까?


125

Rails 3에서이 검색이 있습니다.

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

그러나 나는 :date => p[:date]조건이 동등해야 :date > p[:date]합니다. 어떻게 할 수 있습니까? 읽어 주셔서 감사합니다.

답변:


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

또는 모든 것을 SQL 표기법으로 변환 할 수도 있습니다.

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

2
안전합니까? 내 말은 p [: date]가 사용자 입력에서 나온다면 SQL 주입을 일으킬 수 있습니까?
MhdSyrwan

7
때문에 안전 where()합니다. 를 사용 where()하면 입력이 자동으로 이스케이프됩니다.
Simone Carletti 2012

34
Simone의 말은 전적으로 사실이 아닙니다. where()변수 대신 물음표가있는 위에 표시된 형식으로 사용되는 경우 입력을 자동으로 이스케이프하고 나중에 함수 호출에 나열합니다. 다음과 같이 사용하는 것은 안전하지 않습니다.Note.where("date > #{p[:date]}")
bdx

4
또한 둘 다 필드 가있는 모델을 병합하는 경우 where("user_id = ?",current_user.id)보다 사용하는 것이 더 위험 합니다. 원시 SQL 표기법을 사용한다는 것은 테이블 설명을 직접 포함해야 함을 의미합니다 . 예 : . where(user_id: current_user.id)user_idwhere("notes.user_id = ?",current_user.id)
DreadPirateShawn

1
시간대 때문에 조심해야합니다. ""와 함께 사용하면 Rails가 데이터베이스로 직접 이동하고 데이터베이스에서 날짜는 UTC로 저장되지만 예를 들어 UTC + 5로 저장되어야하며 이는 올바르지 않습니다. 그러니 p [날짜]를 현재 UTC로 변환하기 전에 확인하십시오
Paulo Tarud

70

열 이름이 모호한 문제가 발생하면 다음을 수행 할 수 있습니다.

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
어떤 이유로 PostgreSQL 서버에서 Simone의 "where"메서드를 사용하여 열을 찾을 수 없다는 오류가 발생했지만 SQLite에서 작동했습니다. 귀하의 방법은 두 가지 모두에서 작동했습니다.
plackemacher

2

다음을 사용해 볼 수 있습니다.

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

SQL에서 동등

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

결과는 다음과 같습니다.

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

그리고 나도 변했어

order('date ASC, created_at ASC')

에 대한

order(:fecha, :created_at)

0

Rails 6.1where조건 에서 비교 연산자에 대한 새로운 '구문'을 추가했습니다 . 예를 들면 다음과 같습니다.

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

따라서 쿼리를 다음과 같이 다시 작성할 수 있습니다.

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

여기에 더 많은 예제를 찾을 수있는 PR 링크가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.