[RUBY-ON-RAILS] 어떻게 체인 범위 쿼리에 대한 OR 대신 AND?
RUBY-ON-RAILS어떻게 체인 범위 쿼리에 대한 OR 대신 AND?
나는 Rails3, 액티브을 사용하고 있습니다
그냥 내가 AND 대신에 범위 OR 문을 체인 수있는 방법을 궁금해.
EG
Person.where(:name => "John").where(:lastname => "Smith")
일반적으로 반환한다 :
name = 'John' AND lastname = 'Smith'
하지만 내가 좋아하는 것 :
`name = 'John' OR lastname = 'Smith'
해결법
-
==============================
1.당신은 할 것
당신은 할 것
Person.where('name=? OR lastname=?', 'John', 'Smith')
지금, (일부 타사 보석을 사용하지 않고있다) 새로운 AR3 구문에 의해 다른 또는 지원이되지 않습니다.
-
==============================
2.이 풀의 요청에 따라, 레일 (5)는 이제 쿼리를 체인에 대해 다음 구문을 지원합니다 :
이 풀의 요청에 따라, 레일 (5)는 이제 쿼리를 체인에 대해 다음 구문을 지원합니다 :
Post.where(id: 1).or(Post.where(id: 2))
이 보석을 통해 레일 4.2에 기능의 백 포트도 있습니다.
-
==============================
3.사용 ARel
사용 ARel
t = Person.arel_table results = Person.where( t[:name].eq("John"). or(t[:lastname].eq("Smith")) )
-
==============================
4.그냥 도움말을 동일한 열 또는 쿼리의 배열 구문을 게시 개 친구.
그냥 도움말을 동일한 열 또는 쿼리의 배열 구문을 게시 개 친구.
Person.where(name: ["John", "Steve"])
-
==============================
5.Rails4 업데이트
Rails4 업데이트
더 3 자 보석을 필요로하지 않는다
a = Person.where(name: "John") # or any scope b = Person.where(lastname: "Smith") # or any scope Person.where([a, b].map{|s| s.arel.constraints.reduce(:and) }.reduce(:or))\ .tap {|sc| sc.bind_values = [a, b].map(&:bind_values) }
올드 대답
더 3 자 보석을 필요로하지 않는다
Person.where( Person.where(:name => "John").where(:lastname => "Smith") .where_values.reduce(:or) )
-
==============================
6.또한 SQL 물건과 코드를 혼합하지 MetaWhere 보석을 사용할 수 있습니다 :
또한 SQL 물건과 코드를 혼합하지 MetaWhere 보석을 사용할 수 있습니다 :
Person.where((:name => "John") | (:lastname => "Smith"))
-
==============================
7.https://github.com/rails/rails/pull/9052 : 레일이 점을 얻기 위해 기존 풀 요청이 같은 경우 사람이 일에 업데이트 된 대답을 찾고, 그것은 보인다.
https://github.com/rails/rails/pull/9052 : 레일이 점을 얻기 위해 기존 풀 요청이 같은 경우 사람이 일에 업데이트 된 대답을 찾고, 그것은 보인다.
액티브 (https://gist.github.com/j-mcnally/250eaaceef234dd8971b)는 다음을 수행 할 수 있습니다위한 @ J-맥널리의 원숭이 패치에 감사 :
Person.where(name: 'John').or.where(last_name: 'Smith').all
더욱 중요한 것은 체인 능력과 또는 스코프입니다 :
scope :first_or_last_name, ->(name) { where(name: name.split(' ').first).or.where(last_name: name.split(' ').last) } scope :parent_last_name, ->(name) { includes(:parents).where(last_name: name) }
그럼 당신은 부모 성을 가진 성이나 이름 또는 모든 사람을 찾을 수 있습니다
Person.first_or_last_name('John Smith').or.parent_last_name('Smith')
이것의 사용하지 최고의 예는 있었으나 결국 질문을 맞게하려고합니다.
-
==============================
8.나 (4.2.5 레일)의 경우에만 다음과 같이 작동합니다 :
나 (4.2.5 레일)의 경우에만 다음과 같이 작동합니다 :
{ where("name = ? or name = ?", a, b) }
-
==============================
9.당신은 3.0 레일을 사용하는 경우이 MetaWhere에 대한 좋은 후보가 될 것이지만, 레일 3.1 일을하지 않습니다. 대신 squeel을 시도 할 수 있습니다. 그것은 동일한 저자에 의해 만들어졌다. 여기가 OR 기반의 체인을 수행 할 것 어떻게 것 :
당신은 3.0 레일을 사용하는 경우이 MetaWhere에 대한 좋은 후보가 될 것이지만, 레일 3.1 일을하지 않습니다. 대신 squeel을 시도 할 수 있습니다. 그것은 동일한 저자에 의해 만들어졌다. 여기가 OR 기반의 체인을 수행 할 것 어떻게 것 :
Person.where{(name == "John") | (lastname == "Smith")}
당신은 많은 다른 멋진 것들 사이에, 믹스 앤 매치 AND / OR 수 있습니다.
-
==============================
10.레일의 업데이트 된 버전 / 액티브는 기본적으로이 구문을 지원할 수 있습니다. 그것은 비슷한에 보일 것입니다 :
레일의 업데이트 된 버전 / 액티브는 기본적으로이 구문을 지원할 수 있습니다. 그것은 비슷한에 보일 것입니다 :
Foo.where(foo: 'bar').or.where(bar: 'bar')
이 풀 https://github.com/rails/rails/pull/9052 요청에 명시된 바와
지금은 단순히 다음과 고집하는 것은 잘 작동합니다 :
Foo.where('foo= ? OR bar= ?', 'bar', 'bar')
-
==============================
11.레일 4 + 범위 + Arel
레일 4 + 범위 + Arel
class Creature < ActiveRecord::Base scope :is_good_pet, -> { where( arel_table[:is_cat].eq(true) .or(arel_table[:is_dog].eq(true)) .or(arel_table[:eats_children].eq(false)) ) } end
내가 불러야과 행운와라는 이름의 범위를 체인했지만,이 설정된 부울 아무것도를 찾는 일했다. SQL처럼 생성
SELECT 'CREATURES'.* FROM 'CREATURES' WHERE ((('CREATURES'.'is_cat' = 1 OR 'CREATURES'.'is_dog' = 1) OR 'CREATURES'.'eats_children' = 0))
-
==============================
12.4 레일
4 레일
scope :combined_scope, -> { where("name = ? or name = ?", 'a', 'b') }
-
==============================
13.당신이 (즉, 두 개의 범위를 결합하려는)을 "또는"문을 포함하도록 수동으로 where 절을 쓸 수없는 경우에는 노동 조합을 사용할 수 있습니다 :
당신이 (즉, 두 개의 범위를 결합하려는)을 "또는"문을 포함하도록 수동으로 where 절을 쓸 수없는 경우에는 노동 조합을 사용할 수 있습니다 :
Model.find_by_sql("#{Model.scope1.to_sql} UNION #{Model.scope2.to_sql}")
(출처 : 액티브 쿼리 연합)
이 중 쿼리와 일치하는 모든 레코드를 반환 것입니다. 그러나,이 배열이 아닌 arel를 반환합니다. https://gist.github.com/j-mcnally/250eaaceef234dd8971b : 당신이 정말 arel을 반환하려는 경우, 당신은이 요점을 체크 아웃.
이는 당신이 원숭이 패치 레일을 신경 쓰지 않는 한, 일을 할 것입니다.
-
==============================
14.당신이 (명시 적으로 전체 데이터 세트 작업 대신) 범위를 제공하기 위해 찾고 있다면 여기에 당신이 레일 (5)와 함께해야 할 일이다 :
당신이 (명시 적으로 전체 데이터 세트 작업 대신) 범위를 제공하기 위해 찾고 있다면 여기에 당신이 레일 (5)와 함께해야 할 일이다 :
scope :john_or_smith, -> { where(name: "John").or(where(lastname: "Smith")) }
또는:
def self.john_or_smith where(name: "John").or(where(lastname: "Smith")) end
-
==============================
15.또한이 관련 질문을 참조하십시오 여기, 여기와 여기에
또한이 관련 질문을 참조하십시오 여기, 여기와 여기에
레일 4은이 문서와이 원래의 답변에 따라
Person .unscoped # See the caution note below. Maybe you want default scope here, in which case just remove this line. .where( # Begin a where clause where(:name => "John").where(:lastname => "Smith") # join the scopes to be OR'd .where_values # get an array of arel where clause conditions based on the chain thus far .inject(:or) # inject the OR operator into the arels # ^^ Inject may not work in Rails3. But this should work instead: .joins(" OR ") # ^^ Remember to only use .inject or .joins, not both ) # Resurface the arels inside the overarching query
말에 기사의주의 사항을 참고 :
-
==============================
16.squeel 보석이 작업을 수행 할 수있는 매우 쉬운 방법을 제공합니다 (전 @의 coloradoblue의 방법 등이 내가 사용하는 뭔가) :
squeel 보석이 작업을 수행 할 수있는 매우 쉬운 방법을 제공합니다 (전 @의 coloradoblue의 방법 등이 내가 사용하는 뭔가) :
names = ["Kroger", "Walmart", "Target", "Aldi"] matching_stores = Grocery.where{name.like_any(names)}
-
==============================
17.원래의 질문에 대한 대답 그래서, 당신은 대신에 '나'로 범위를 가입 '과'수는 "아니오 당신이 할 수없는"것으로 보인다. 하지만 당신은 코드에게 일을 완전히 다른 범위 또는 쿼리를 손으로, 또는 액티브 예에서 다른 프레임 워크를 사용할 수 있습니다 MetaWhere 또는 Squeel. 내 경우에는 유용하지 않음
원래의 질문에 대한 대답 그래서, 당신은 대신에 '나'로 범위를 가입 '과'수는 "아니오 당신이 할 수없는"것으로 보인다. 하지만 당신은 코드에게 일을 완전히 다른 범위 또는 쿼리를 손으로, 또는 액티브 예에서 다른 프레임 워크를 사용할 수 있습니다 MetaWhere 또는 Squeel. 내 경우에는 유용하지 않음
나는 '조금 더 선택 이상하지, 그것은 깨끗한 노조의 난장판을 만드는 ASC에 의해 순서를 포함 pg_search에 의해 생성 된 범위를, OR 처리하고 있습니다. 나는 pg_search에서 할 수없는 물건을 수행하는 손수 범위로에 '또는'합니다. 그래서 이런 식으로해야했다했습니다.
Product.find_by_sql("(#{Product.code_starts_with('Tom').to_sql}) union (#{Product.name_starts_with('Tom').to_sql})")
즉 SQL로 범위를 설정,이를 함께, 각각의 주위에 노동 조합을 괄호를 넣고 find_by_sql 생성 된 SQL을 사용하여. 그것은 비트 쓰레기지만,이 작업을 수행합니다.
pg_search, 나는 그런 식으로 그것을 할 싶습니다하지만 '이름'필드는 hstore, pg_search 수없는 핸들입니다 "[: 코드 : 이름]에 대해"아니, 내가 사용할 수 있습니다 말하지 않는다 아직. 이름으로 범위가 있어야한다 그래서 손으로 제작하고 pg_search 범위와 UNION을.
-
==============================
18.이것은 매우 편리한 방법이며 레일 5에서 잘 작동합니다 :
이것은 매우 편리한 방법이며 레일 5에서 잘 작동합니다 :
Transaction .where(transaction_type: ["Create", "Correspond"]) .or( Transaction.where( transaction_type: "Status", field: "Status", newvalue: ["resolved", "deleted"] ) ) .or( Transaction.where(transaction_type: "Set", field: "Queue") )
-
==============================
19.
names = ["tim", "tom", "bob", "alex"] sql_string = names.map { |t| "name = '#{t}'" }.join(" OR ") @people = People.where(sql_string)
from https://stackoverflow.com/questions/3684311/how-to-chain-scope-queries-with-or-instead-of-and by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 레일의 단수 또는 복수의 컨트롤러 및 도우미 이름 (0) | 2020.02.06 |
---|---|
[RUBY-ON-RAILS] 3 레일 : 임의의 레코드를 가져 (0) | 2020.02.06 |
[RUBY-ON-RAILS] Heroku가 배치 오류 H10 (APP 추락) (0) | 2020.02.06 |
[RUBY-ON-RAILS] 레일의 많은 관계로 많은 만들기 (0) | 2020.02.06 |
[RUBY-ON-RAILS] 어떻게 루비 온 레일즈 콘솔에서 컨트롤러 / 뷰 헬퍼 메소드를 호출 할 수 있습니다? (0) | 2020.02.06 |