我想找到所有注释,其主体是:
>等于“?”
>或
>喜欢“[?]”
最好的方法是什么?
我想尽可能使用SearchLogic,但是SearchLogic允许您执行以下各项操作:
> Annotation.body_equals(‘?’)
> Annotation.body_like(‘[?]’)
并且你总是可以将它们链接在一起:Annotation.body_equals(‘?’).body_like(‘[?]’)
我不确定如何将它们与OR结合起来.
Note that you can combine named scopes with OR
if their argument is the same.例如,我可以这样做:
Annotation.body_equals_or_body_like('?')
但这没有用.
请注意,我并不依赖于SearchLogic,但对于不需要破坏其抽象的解决方案来说,它会很棒.
解决方法
我找不到任何简单的解决方案,但这个问题引起了我的兴趣,所以我推出了自己的解决方案:
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