Strict Standards: Non-static method themeGluedIdeas_Subtle::initOptions() should not be called statically in /home/riopro/www/blog.riopro.com.br/wp-content/themes/gluedideas_subtle/header.php on line 19
Riopro Blog - » Usando o SearchLogic 2 integrado as tags do acts-as-taggable-on

Usando o SearchLogic 2 integrado as tags do acts-as-taggable-on



Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in /home/riopro/www/blog.riopro.com.br/wp-includes/formatting.php on line 82

O SearchLogic 2 é realmente muito bom. Estamos usando em nossas novas aplicações e a produtividade obtida com ele é imensa. Nada mais de criar helpers próprios, vários named_scopes. Agora só criamos o que for estritamente necessário. Como por exemplo quando escolhemos o acts-as-taggable-on para associar tags a modelos.

Aqui vamos discutir como integrar o SearchLogic com o acts-as-taggable-on de forma a usarmos o mesmo padrão de buscas. Não é objetivo explicar como ambos funcionam, até porque o Readme de ambas as gems estão muito bem feitas. O do SearchLogic, então, é perfeito.

Bom, mãos à massa. Para esse exemplo vamos supor que você possui um modelo chamado Supplier na sua app e que já está usando ele com o acts-as-taggable-on, dessa forma:


# app/models/supplier.rb
acts_as_taggable_on :tags

E que seu controller de fornecedores já cria a variável @search como descrito no Readme do SearchLogic:


# app/controllers/suppliers_controller.rb
def index
@search = Supplier.search(params[:search])
@suppliers = @search.all
end

O que ocorre é que o acts-as-taggable-on incluí uma série de métodos de classe e de instância ao seu modelo, e mesmo um named_scope chamado tagged_with. Seria então fácil usar o named_scope para a busca usando o SearchLogic. Seria, como descrito no seu Readme assim na view (opa, aqui é importante saber que vou escrever em Haml porque erb é coisa do passado):


# app/views/suppliers/index.html.haml
- form_for @search do |f|
%p
= f.label Buscar:
%span.info por descrição ou número do contrato
%br/
= f.text_field :tagged_with
= submit_tag '', :disable_with => '...', :class => "search"

Nota: A partir da versão 2.0.6 do acts-as-taggable-on, o named scope tagged_with já possui um default para tags. E no Rails 3 named_scope para a se chamar apenas scope. Mas o resto continua válido.

Isso seria ótimo. Só que isso vai falhar! O problema é que o named_scope tagged_with precisa de 2 parâmetros ao invés de 1. Ele precisaria que você usasse dessa forma


Supplier.tagged_with "material de informática", :on => :tags

Pois é, esse raio desse :on => :tags vai te quebrar.

Aqui uma nota, esse :on é proposital, e não um bug. Isso ocorre porque ao
invés de apenas :tags, você poderia ter tipos diferentes de associações,
como por exemplo você poderia ter uma lista de tags para indicar quais os
tipos de pagamentos que seu fornecedor aceita :payment_methods e outro
que tipo de produtos ele fornece :product_types (eu acho isso inútil, mas
vá lá).

Para não termos esse problema, criamos um novo named_scope dessa forma:


named_scope :tagged_with_on_tags, lambda { |tag|
# match_all é para que as condições sejam associativas.
# ou seja, o objeto tem que ter todas as tags descritas
options = { :on => :tags, :match_all => true }
find_options_for_find_tagged_with(tag, options)
}

Onde, find_options_for_find_tagged_with é um método da própria gem do acts-as-taggable-on. Outro detalhe é o uso da option :match_all => true para que o named_scope procure os fornecedores que possuam todas as tags digitadas. Se não fizermos isso, ele procura por todos os fornecedores que possuam ao menos uma das tags E nossa view ficaria assim:


# app/views/suppliers/index.html.haml
- form_for @search do |f|
%p
= f.label Buscar:
%span.info por descrição ou número do contrato
%br/
= f.text_field :tagged_with_on_tags
= submit_tag '', :disable_with => '...', :class => "search"

Para o teste, usando o rspec, o objetivo foi garantir a existência do named_scope e testar algumas atributos que são usados pelo método find_options_for_find_tagged_with. O objetivo não foi testar algo que já possui teste, mas sim tentar garantir que saberemos se o método um dia foi depreciado, stubado (ou seja, continuar existindo mas não fazer nada) ou coisas do tipo. Mas não é garantido.


Supplier.tagged_with_on_tags("UMA_TAG_SINISTRA").proxy_options[:joins].should_not be_blank
Supplier.tagged_with_on_tags("UMA_TAG_SINISTRA").proxy_options[:group].should_not be_blank
Supplier.tagged_with_on_tags("UMA_TAG_SINISTRA").proxy_options[:conditions].should =~ (/(UMA_TAG_SINISTRA[a-z0-9_' ]+)/i)

Espero que seja útil.

Informações e Links

Junte-se comentando, lendo o que os outros dizem ou colocando um link a partir do seu blog.


Outros Artigos

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Gdd Brasil 2009 - evento em geral

Strict Standards: Only variables should be assigned by reference in /home/riopro/www/blog.riopro.com.br/wp-includes/post.php on line 117
Atualize seu s3cmd para 0.9.9 no Ubuntu 9.04

Comente

Tire um tempo para comentar e nos dizer o que você acha. Alguns códigos HTML são permitidos para formatação.

Comentários dos Leitores

Seja o primeiro a comentar!