[RUBY-ON-RAILS] OR (대신 AND)와 함께 두 개의 명명 범위를 결합
RUBY-ON-RAILSOR (대신 AND)와 함께 두 개의 명명 범위를 결합
나는 그의 몸 중 모든 주석을 찾으려면 :
이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
SearchLogic 당신이 다음의 각을 수행 할 수 있지만 나는 가능하면 SearchLogic를 사용하려면,하지만 것입니다 :
그리고 당신은 항상 그들을 함께 체인 수 있습니다. Annotation.body_equals ( '?') body_like ( '[?])
나는 OR와 조합하는 방법을 모르겠어요.
그들의 인수가 동일한 경우 OR로 이름 범위를 결합 할 수 있습니다. 예를 들어, 내가 할 수있는 :
Annotation.body_equals_or_body_like('?')
그러나이 도움이되지 것입니다.
내가 SearchLogic에 부착 아니지만, 그것의 추상화를 깨는 필요로하지 않는 솔루션에 대한 좋은 것입니다 있습니다.
해결법
-
==============================
1.나는 어떤 간단한 해결책을 찾을 수 없습니다,하지만 난 내 자신의 솔루션을 압연 있도록이 문제는 나에게 흥미 :
나는 어떤 간단한 해결책을 찾을 수 없습니다,하지만 난 내 자신의 솔루션을 압연 있도록이 문제는 나에게 흥미 :
class ActiveRecord::Base def self.or_scopes(*scopes) # Cleanup input scopes.map! do |scope| scope = scope.respond_to?(:to_a) ? scope.to_a : [*scope] scope.unshift(scope.shift.to_sym) end # Check for existence of scopes scopes.each{|scope| raise ArgumentError, "invalid scope: #{scope.first}" unless self.scopes.has_key?(scope.first) } conditions = scopes.map do |scope| scope = self.scopes[scope.first].call(self, *scope[1..-1]) self.merge_conditions(scope.proxy_options[:conditions]) end or_conditions = conditions.compact.join(" OR ") merged_scopes = scopes.inject(self){|merged, scope| merged.scopes[scope.first].call(self, *scope[1..-1]) } # We ignore other scope types but so does named_scopes find_options = merged_scopes.scope(:find).merge(:conditions => or_conditions) self.scoped(find_options) end end
다음 설치를 고려하십시오
class Person < ActiveRecord::Base named_scope :men, :conditions => { :sex => 'M' } named_scope :women, :conditions => { :sex => 'F' } named_scope :children, :conditions => "age < 18" named_scope :named, lambda{|name| { :conditions => { :name => name } } } end
당신은 같은 범위의 일련의 이름과 전화 :
Person.or_scopes(:women, :children)
이 같은 범위를 반환합니다 :
Person.or_scopes(:women, :children).proxy_options # => {:conditions=>"(`people`.`sex` = 'F') OR (age < 18)"}
범위가 매개 변수를 필요로 할 때 당신은 또한 배열의 배열로 호출 할 수 있습니다 :
Person.or_scopes(:women, [:named, 'Sue']).proxy_options # => {:conditions=>"(`people`.`sex` = 'F') OR (`people`.`name` = 'Sue')"}
귀하의 경우 호레이스, 당신은 다음을 사용할 수 있습니다 :
Annotation.or_scopes([:body_equals, '?'], [:body_like, '[?']).all
-
==============================
2.'와 같은'는 결과도 '등호'결과를 포함하지 않을까요?
'와 같은'는 결과도 '등호'결과를 포함하지 않을까요?
또한 정말로 긴 이름 범위를 만들기 위해 다른 사람의 말에 명명 된 범위를 사용할 수 있습니다. Searchlogic 문서 도구에서 (이 방법은 나에게 longwinded 조금 보인다)
User.username_or_first_name_like("ben") => "username LIKE '%ben%' OR first_name like'%ben%'" User.id_or_age_lt_or_username_or_first_name_begins_with(10) => "id < 10 OR age < 10 OR username LIKE 'ben%' OR first_name like'ben%'"
아니면 중복을 제거하는 동안 검색 결과 배열을 결합하는 노동 조합을 사용할 수 있습니다 :
@equal_results = Annotation.body_equals('?') @like_results = Annotation.body_like('[?]') @results = @equal_results | @like_results
-
==============================
3.레일 2.x를 들어, 시뮬레이션 또는 다음 명명 된 범위를 사용할 수 있습니다 :
레일 2.x를 들어, 시뮬레이션 또는 다음 명명 된 범위를 사용할 수 있습니다 :
__or_fn = lambda do |*scopes| where = [] joins = [] includes = [] # for some reason, flatten is actually executing the scope scopes = scopes[0] if scopes.size == 1 scopes.each do |s| s = s.proxy_options begin where << merge_conditions(s[:conditions]) rescue NoMethodError where << scopes[0].first.class.merge_conditions(s[:conditions]) end joins << s[:joins] unless s[:joins].nil? includes << s[:include] unless s[:include].nil? end scoped = self scoped = scoped.includes(includes.uniq.flatten) unless includes.blank? scoped = scoped.joins(joins.uniq.flatten) unless joins.blank? scoped.where(where.join(" OR ")) end named_scope :or, __or_fn
하자가 위의 예를 사용하여이 기능을 사용합니다.
q1 = Annotation.body_equals('?') q2 = Annotation.body_like('[?]') Annotation.or(q1,q2)
위의 코드는 하나의 쿼리를 실행합니다. 분기와 2 분기 쿼리의 결과를 보유하지 않는, 오히려 자신의 클래스는 액티브 :: NamedScope이다 :: 범위.
또는 named_scope는 이러한 쿼리를 결합하고, OR와 조건을 결합한다.
당신 수 또한 둥지 관찰 보고서,이 인위적인 예처럼 :
rabbits = Animal.rabbits #<Animal id: 1 ...> puppies = Animal.puppies #<Animal id: 2 ...> snakes = Animal.snakes #<Animal id: 3 ...> lizards = Animal.lizards #<Animal id: 4 ...> Animal.or(rabbits, puppies) [#<Animal id: 1 ...>, #<Animal id: 2 ...>] Animal.or(rabbits, puppies, snakes) [#<Animal id: 1 ...>, #<Animal id: 2 ...>, #<Animal id: 3 ...>]
때문에 또는 리턴한다 액티브 :: NamedScope :: 범위 자체가, 우리가 정말 미친 갈 수 있습니다 :
# now let's get crazy or1 = Animal.or(rabbits, puppies) or2 = Animal.or(snakes, lizards) Animal.or(or1, or2) [#<Animal id: 1 ...>, #<Animal id: 2 ...>, #<Animal id: 3 ...>, #<Animal id: 4...>]
나는 시도하지 않은 있지만,이 예제의 대부분은, 레일 3의 범위를 사용하여 잘 작동한다고 생각합니다.
뻔뻔한 자기 홍보의 비트 -이 기능은 fake_arel 보석에서 사용할 수 있습니다.
-
==============================
4.나는 나에게 너무 복잡 보았다 "또는"두 named_scopes 모든 답변에 대한 답을 찾고이 질문을 온. 나는 조금을 조사하고 트릭을 수행 추가적인라고 named_scope "또는"을 사용하여 솔루션을 발견했다.
나는 나에게 너무 복잡 보았다 "또는"두 named_scopes 모든 답변에 대한 답을 찾고이 질문을 온. 나는 조금을 조사하고 트릭을 수행 추가적인라고 named_scope "또는"을 사용하여 솔루션을 발견했다.
주어진 예를 들면 다음과 같습니다
Annotation.body_equals('?') Annotation.body_like('[?]')
두 구조의 선택은 주석 레코드를 반환하는 named_scope 개체를 반환
지금 우리는 같은 매개 변수로 두 개의 명명 범위를 기대하고 또 다른 이름 범위를 정의 :
named_scope :or, lambda { |l, r| { :conditions => "annotations.id IN (#{l.send(:construct_finder_sql,{:select => :id})}) or " + "annotations.id IN (#{r.send(:construct_finder_sql,{:select => :id})})" }}
그런 다음 사용할 수 있습니다 :
Annotation.or(Annotation.body_equals('?'), Annotation.body_like('[?]'))
이 같은 쿼리를 작성합니다 :
select * from annotations where (annotations.id IN (select id from annotations where body='?') or (annotations.id IN (select id from annotations where body like '%?%')
당신이 후에 무엇인지 어느
또는도 named_scope, 그것은 또 다른 또는 기타 포함 named_scopes 체인 가능하다 :
Annotation.or(Annotation.or(Annotation.body_equals('?'), Annotation.body_like('[?]')), Annotation.some_other)
-
==============================
5.아마도 그건
아마도 그건
Annotation.body_equals_or_body_like(['?', '[?]'])
from https://stackoverflow.com/questions/1482940/combine-two-named-scopes-with-or-instead-of-and by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 루비 온 레일즈 : 고급 검색 (0) | 2020.03.04 |
---|---|
[RUBY-ON-RAILS] 분할 오류는 RVM와 맥 OSX에 레일 (0) | 2020.03.04 |
[RUBY-ON-RAILS] 같은 페이지에 여러 개의 비 중첩 모델 생성 (0) | 2020.03.04 |
[RUBY-ON-RAILS] 루비 텍스트 파일의 중간에 데이터의 줄을 제거하려면 어떻게 (0) | 2020.03.04 |
[RUBY-ON-RAILS] 왜 Heroku가 Windows에서 내 Gemfile.lock을 허용하지 않습니다? (0) | 2020.03.04 |