visual studio microsoft español descargar community ruby-on-rails searchlogic

ruby-on-rails - microsoft - visual studio installer



Combina dos ámbitos con nombre con OR(en lugar de Y) (5)

Quiero encontrar todas las Annotations cuyos cuerpos sean:

  • Igual a "?"
  • o
  • Me gusta "[?]"

¿Cuál es la mejor manera de hacer esto?

Me gustaría usar SearchLogic si es posible, pero aunque SearchLogic te permite hacer cada uno de los siguientes:

  • Annotation.body_equals(''?'')
  • Annotation.body_like(''[?]'')

y siempre puedes encadenarlas juntas: Annotation.body_equals(''?'').body_like(''[?]'')

No estoy seguro de cómo combinarlos con OR

Tenga en cuenta que puede combinar ámbitos con nombre OR si su argumento es el mismo. Por ejemplo, podría hacer:

Annotation.body_equals_or_body_like(''?'')

Pero esto no ayudaría.

Tenga en cuenta que no estoy vinculado a SearchLogic, pero sería genial para una solución que no requiera romper su abstracción.


¿Los resultados ''me gusta'' tampoco incluirían los resultados ''iguales''?

También puede usar un alcance nombrado al final de otro para crear un ámbito con nombre realmente largo. De los documentos de Searchlogic (de esta manera parece un poco largo para mí):

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%''"

O puede usar una unión para combinar las matrices de resultados de búsqueda mientras elimina los duplicados:

@equal_results = Annotation.body_equals(''?'') @like_results = Annotation.body_like(''[?]'') @results = @equal_results | @like_results


Me acerqué a esta pregunta en busca de la respuesta a "o" two named_scopes y todas las respuestas me parecieron demasiado complejas. Investigué un poco y encontré una solución usando un scope_name llamado "or" que hace el truco.

Siguiendo el ejemplo dado:

Annotation.body_equals(''?'') Annotation.body_like(''[?]'')

ambos devuelven un objeto named_scope que constructo selecciona devolver registros de anotación

ahora definimos otro alcance nombrado esperando dos ámbitos con nombre como parámetros como:

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})})" }}

Puede usar:

Annotation.or(Annotation.body_equals(''?''), Annotation.body_like(''[?]''))

Esto creará una consulta como:

select * from annotations where (annotations.id IN (select id from annotations where body=''?'') or (annotations.id IN (select id from annotations where body like ''%?%'')

Que es lo que estabas buscando

Como o también es un named_scope, es posible encadenar con otros named_scopes incluyendo otro o:

Annotation.or(Annotation.or(Annotation.body_equals(''?''), Annotation.body_like(''[?]'')), Annotation.some_other)


No pude encontrar ninguna solución simple, pero este problema me intrigó, así que lancé mi propia solución:

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

Considere la siguiente configuración:

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

Usted lo llama con los nombres de una serie de ámbitos como tal:

Person.or_scopes(:women, :children)

Esto devuelve un alcance como este:

Person.or_scopes(:women, :children).proxy_options # => {:conditions=>"(`people`.`sex` = ''F'') OR (age < 18)"}

También puede llamarlo con una matriz de matrices cuando el alcance requiera parámetros:

Person.or_scopes(:women, [:named, ''Sue'']).proxy_options # => {:conditions=>"(`people`.`sex` = ''F'') OR (`people`.`name` = ''Sue'')"}

En tu caso, Horace, podrías usar lo siguiente:

Annotation.or_scopes([:body_equals, ''?''], [:body_like, ''[?'']).all


Para Rails 2.x, puede usar el siguiente alcance nombrado para simular OR:

__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

Usemos esta función usando su ejemplo anterior.

q1 = Annotation.body_equals(''?'') q2 = Annotation.body_like(''[?]'') Annotation.or(q1,q2)

El código anterior ejecuta solo una consulta. q1 y q2 no contienen los resultados de la consulta, sino que su clase es ActiveRecord::NamedScope::Scope .

The or named_scope combina estas consultas y une las condiciones con un OR.

También puede anidar OR, como en este ejemplo artificial:

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 ...>]

Porque or devuelve un ActiveRecord::NamedScope::Scope sí mismo, podemos ActiveRecord::NamedScope::Scope realmente locos:

# 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...>]

Creo que la mayoría de estos ejemplos funcionarían bien usando scope s en Rails 3, aunque no lo he intentado.

Un poco de autopromoción descarada: esta funcionalidad está disponible en la gema fake_arel .


Probablemente es

Annotation.body_equals_or_body_like([''?'', ''[?]''])