Estou implementando uma funcionalidade para rastrear quais artigos um usuário leu.
create_table "article", :force => true do |t|
t.string "title"
t.text "content"
end
Esta é minha migração até agora:
create_table :user_views do |t|
t.integer :user_id
t.integer :article_id
end
A tabela user_views sempre será consultada para procurar ambas as colunas, nunca apenas uma. Minha pergunta é como meu índice deve ser. Existe uma diferença na ordem dessas tabelas, deve haver mais algumas opções para isso ou algo assim. Meu banco de dados de destino é o Postgres.
add_index(:user_views, [:article_id, :user_id])
Obrigado.
ATUALIZAÇÃO:
Como apenas uma linha contendo os mesmos valores em ambas as colunas pode existir (visto que, ao saber se user_id LEU article_id), devo considerar a opção: unique? Se não me engano, isso significa que não tenho que fazer nenhuma verificação por conta própria e simplesmente inserir uma inserção sempre que um usuário visitar um artigo.
fonte
Respostas:
A ordem importa na indexação.
[:user_id, :article_id]
, poderá realizar uma consulta rápida emuser_id
ouuser_id AND article_id
, mas NÃO emarticle_id
.Sua
add_index
linha de migração deve ser semelhante a esta:Pergunta sobre a opção 'única'
Uma maneira fácil de fazer isso no Rails é usar
validates
em seu modelo com ouniqueness
seguinte escopo ( documentação ):fonte
validates_uniqueness_of
(e seu primovalidates uniqueness:
) são propensos a condições de corridaApenas um aviso sobre a verificação da unicidade no momento da validação vs. no índice: o último é feito pelo banco de dados enquanto o primer é feito pelo modelo. Como pode haver várias instâncias simultâneas de um modelo em execução ao mesmo tempo, a validação está sujeita a condições de corrida, o que significa que pode falhar em detectar duplicatas em alguns casos (por exemplo, enviar duas vezes o mesmo formulário ao mesmo tempo).
fonte