6.3 Módulos do SocialFramework
6.3.1 Módulo de Usuários
d e v i s e _ f o r : u s e r s , c l a s s _ n a m e : ’ S o c i a l F r a m e w o r k : : U s e r ’, c o n t r o l l e r s : { s e s s i o n s : ’ u s e r s / s e s s i o n s ’,
r e g i s t r a t i o n s : ’ n e w _ r e g i s t r a t i o n _ c o n t r o l l e r _ p a t h ’, p a s s w o r d s : ’ u s e r s / p a s s w o r d s ’}
Código 6.16 – Configuração de umacontroller
A controller de registro foi estendida, e a nova controller foi adicionada nas con-figurações de rotas do Devise.
6.2.6 Configuração das Views
Para adicionar as views do Devise na aplicação, o SocialFramework possui um gerador para executar esta tarefa. Para executá-lo, deve-se usar o seguinte comando:
$ r a i l s g e n e r a t e s o c i a l _ f r a m e w o r k : v i e w s
Código 6.17 – Geração das views
Para adicionar umaview específica, deve-se usar o parâmetro ‘-v’, e passar o nome das views, como no exemplo a seguir:
$ r a i l s g e n e r a t e s o c i a l _ f r a m e w o r k : v i e w s −v r e g i s t r a t i o n s s e s s i o n s p a s s w o r d s
Código 6.18 – Geração das views
Este comando irá adicionar as views “registrations”, “sessions” e “passwords” na aplicação. Outras views são: “confirmations”, “mailer” e “unlocks”. Inicialmente, o So-cialFramework adiciona as views “registrations” e “sessions” na aplicação, fornecendo autenticação e registro para os usuários.
com o nome do relacionamento. Podem existir múltiplos relacionamentos entre os mesmos usuários. Cada relacionamento é representado com uma aresta.
Para criar um novo relacionamento entre dois usuários, deve-se utilizar o método
‘create_relationship’, definido na classe de usuário. Esse método possui a seguinte assi-natura:
c r e a t e _ r e l a t i o n s h i p ( d e s t i n y , l a b e l , b i d i r e c t i o n a l=t r u e , a c t i v e=f a l s e)
Código 6.19 – Método para criar relacionamento
O usuário que pede o relacionamento deve chamar este método e passar o usuário de destino e rótulo para o relacionamento. Por padrão, é criado um relacionamento bi-direcional e inativo entre esses usuários. É possível mudar esse comportamento passando outros parâmetros para o método.
Para ativar o relacionamento criado, é necessária uma confirmação. Assim, o usuá-rio de destino deve invocar o método ‘confirm_relationship’. Esse método possui a seguinte assinatura:
c o n f i r m _ r e l a t i o n s h i p ( u s e r , l a b e l )
Código 6.20 – Método para confirmar relacionamento
É necessário passar como parâmetro o usuário de origem e o rótulo com o tipo de relacionamento. O único usuário que pode confirmar o relacionamento é o usuário de destino.
Para remover algum relacionamento, os usuários devem chamar o método ‘re-move_relationship’, passando outro usuário do relacionamento e o rótulo do relaciona-mento. Esse método possui a seguinte assinatura:
r e m o v e _ r e l a t i o n s h i p ( d e s t i n y , l a b e l )
Código 6.21 – Método para remover relacionamento
A classe de usuário fornece também um método para obter os usuários relacionados a um outro usuário específico. Para isso, deve-se chamar o seguinte método:
r e l a t i o n s h i p s ( l a b e l , s t a t u s = t r u e , c r e a t e d _ b y = " any ")
Código 6.22 – Método para recuperar usuários com um tipo de relacionamento O rótulo representa o tipo de relacionamento a partir do qual se deseja obter os usuários. O status é usado para os usuários com relacionamentos ativos ou inativos. O padrão é true. O parâmetro ‘created_by’ é usado para especificar qual usuário pode ter criado o relacionamento; caso seja “any”, qualquer usuário poderá ter criado o relacio-namento; caso seja “self”, os relacionamentos devem possuir como usuário de origem o próprio usuário ou, caso seja “other”, os relacionamentos, devem possuir, como usuário de destino, o próprio usuário.
O módulo de usuários usa um grafo para fornecer algumas funcionalidades, como buscas na rede e sugestões de relacionamentos. Todas estas funcionalidades podem ser acessadas através da classeGraphContext, que é usada para implementação doPadrão Strategy.
Informações mais detalhadas sobre essa implementação podem ser encontradas na seção Hotspotsdeste capítulo.
O grafo pode ser acessado a partir do método ‘graph’, que está presente na classe de usuário. No momento de login, o grafo é construído até a profundidade especificada no initializer ‘social_framework.rb’, na variável ‘depth_to_build’ com o usuário logado como raiz (root). O valor de profundidade padrão definido é 3, e pode ser alterado conforme as necessidades do usuário doframework.
O método ‘graph’ da classe de usuário possui a seguinte assinatura:
g r a p h ( g r a p h _ s t r a t e g y = N e t w o r k H e l p e r : : G r a p h S t r a t e g y D e f a u l t , e l e m e n t s _ f a c t o r y = E l e m e n t s F a c t o r y D e f a u l t )
Código 6.23 – Método acessar o grafo de usuários
Os parâmetros graph_strategy e elements_factory são usados quando não se está usando a estratégia padrão do grafo ou a fábrica padrão de vértices e arestas. Mais uma vez, a seçãoHotspots detalha esse aspecto.
O método build é o responsável pela construção do grafo, e possui a seguinte assinatura:
b u i l d ( r o o t , a t t r i b u t e s = S o c i a l F r a m e w o r k . a t t r i b u t e s _ t o _ b u i l d _ g r a p h , r e l a t i o n s h i p s = " a l l ")
Código 6.24 – Método para construir o grafo
O parâmetro “root” é o usuário que irá ser a raiz do grafo. O parâmetro “attribu-tes” corresponde aos atributos de usuário e evento que serão mapeados para os vértices.
Por padrão, contém o nome de usuário, o email e o título do evento. O valor padrão desse atributo pode ser alterado no initializer ‘social_framework.rb’. O parâmetro “rela-tionships” representa os tipos de relacionamentos que serão considerados para a construção do grafo, devendo ser uma string para especificar um único relacionamento, ou umarray para especificar mais de um relacionamento. Caso seja passada a string “all”, o grafo é construído considerando todos os relacionamentos. Na ação de login, o grafo é construído com os atributos padrões definidos, além do ‘id’.
Com o grafo construído, é possível sugerir relacionamentos. Para isso, utiliza-se o algoritmo DFS para analisar o terceiro nível do grafo e encontrar relacionamentos comuns, com o tipo especificado no initialize ‘social_framework.rb’, na variável ‘rela-tionship_type_to_suggest’, que possui o seu valor padrão como “friend”. A variável
‘amount_relationship_to_suggest’ especifica a quantidade de relacionamentos comuns
que devem existir entre dois usuários para que estes recebam a sugestão de amizade.
Nesse caso, o valor padrão é cinco. Esse método possui a seguinte assinatura.
s u g g e s t _ r e l a t i o n s h i p s ( t y p e _ r e l a t i o n s h i p s = S o c i a l F r a m e w o r k . r e l a t i o n s h i p _ t y p e _ t o _ s u g g e s t ,
a m o u n t _ r e l a t i o n s h i p s = S o c i a l F r a m e w o r k . a m o u n t _ r e l a t i o n s h i p _ t o _ s u g g e s t )
Código 6.25 – Método para sugerir relacionamento
Considerando os valores padrão, se um usuário ‘A’ e um usuário ‘C’ tem cinco relacionamentos com o tipo “friend” com outros cinco usuários, o sistema irá sugerir ao usuário ‘A’ começar o mesmo relacionamento com o usuário ‘C’, e vice-versa.
A busca no grafo é executada usando o algoritmoBFS. O método da busca possui a seguinte assinatura.
s e a r c h ( map , s e a r c h _ i n _ p r o g r e s s = f a l s e , elements_number = S o c i a l F r a m e w o r k . e l e m e n t s _ n u m b e r _ t o _ s e a r c h )
Código 6.26 – Método para fazer pesquisa
É passado um mapa para ser usado na pesquisa. Este mapa representa as chaves e os valores para comparar com os vértices, por exemplo, o mapa “{username: ‘user’, email:
‘user’, title: ‘event’}” fará com que uma pesquisa retorne qualquer vértice que contém a string ‘user’ no nome de usuário ou no e-mail, ou que contenha a string “event” no título. O parâmetro ‘search_in_progress’ é usado para continuar uma busca para encon-trar mais resultados. Nesse caso, deve-se passar true. O parâmetro ‘elements_number’
define a quantidade de resultados para retornar, sendo este valor especificado no initia-lizer ‘social_framework.rb’, na variável ‘elements_number_to_search’. O valor padrão é cinco.
Um exemplo para continuar uma pesquisa é mostrado no Código6.27. Por padrão, quando se continua a procurar, o parâmetro ‘elements_number’ é usado para incrementar o número máximo de resultados que devem ser retornados. Neste caso, a primeira chamada retorna os primeiros cinco elementos encontrados no grafo; a segunda chamada retorna mais cinco elementos, totalizando no final dez elementos, e assim por diante. O retorno do método é uma hash com duas chaves; a primeira é “users” e seu valor é umarray com os usuários encontrados, e a segunda é “events” e seu valor é um array com os eventos encontrados.
map = { username : ’ u s e r ’, e m a i l : ’ u s e r ’, t i t l e : ’ e v e n t ’} g r a p h . s e a r c h ( map )
g r a p h . s e a r c h ( map , t r u e , 1 0 )
Código 6.27 – Exemplo de continuação de pesquisa
Pode-se alterar o comportamento padrão para continuar pesquisas, passando um bloco para o método. Este bloco irá indicar como o “elements_number” deve ser incre-mentado. Por exemplo:
map = { username : ’ u s e r ’, e m a i l : ’ u s e r ’, t i t l e : ’ e v e n t ’} g r a p h . s e a r c h ( map , f a l s e , 1 )
g r a p h . s e a r c h ( map , t r u e) { | elements_number | elements_number ∗= 2 }
Código 6.28 – Bloco para aumentar o valor do “elements_number”
Nesse caso, o ‘elements_number’ vai dobrar a cada método de pesquisa chamado com esse bloco. Portanto, a primeira chamada retorna um elemento, devido ao valor passado; o segundo dois; a terceira quatro, e assim por diante.
Quando a pesquisa chega ao fim do grafo e ainda não encontrou todos os elementos necessários, uma pesquisa no banco de dados é realizada para completar a pesquisa.