Como selecionar onde o ID no Array Rails ActiveRecord sem exceção
-
10-07-2019 - |
Pergunta
Quando eu tenho uma variedade de IDs, como
ids = [2,3,5]
e eu me apresento
Comment.find(ids)
Tudo funciona bem. Mas quando há ID que não existe, recebo uma exceção. Isso ocorre em geral quando recebo uma lista de IDs que correspondem a algum filtro e do que eu gosto de algo como
current_user.comments.find(ids)
Desta vez, posso ter um ID de comentário válido, que, no entanto, não pertence ao usuário, por isso não é encontrado e recebo uma exceção.
eu tentei find(:all, ids)
, mas retorna todos os registros.
A única maneira de fazer isso agora é
current_user.comments.select { |c| ids.include?(c.id) }
Mas isso me parece uma solução super ineficiente.
Existe uma maneira melhor de selecionar ID na matriz Sem obter exceção em registro inexistente?
Solução
Se estiver apenas evitando a exceção com a qual você está preocupado, a família de funções "find_all_by .." funciona sem jogar exceções.
Comment.find_all_by_id([2, 3, 5])
funcionará mesmo que alguns dos IDs não existam. Isso funciona no
user.comments.find_all_by_id(potentially_nonexistent_ids)
caso também.
Atualização: Rails 4
Comment.where(id: [2, 3, 5])
Outras dicas
ATUALIZAÇÃO: Esta resposta é mais relevante para o Rails 4.x
Fazem isto:
current_user.comments.where(:id=>[123,"456","Michael Jackson"])
O lado mais forte dessa abordagem é que ele retorna um Relation
objeto, ao qual você pode se juntar a mais .where
cláusulas, .limit
cláusulas, etc., o que é muito útil. Ele também permite IDs inexistentes sem jogar exceções.
A sintaxe Ruby mais recente seria:
current_user.comments.where(id: [123, "456", "Michael Jackson"])
Se você precisar de mais controle (talvez precise declarar o nome da tabela), também pode fazer o seguinte:
Model.joins(:another_model_table_name)
.where('another_model_table_name.id IN (?)', your_id_array)
Agora .Find e .find_by_id Os métodos estão depreciados nos trilhos 4. Portanto, podemos usar abaixo:
Comment.where(id: [2, 3, 5])
Funcionará mesmo que alguns dos IDs não existam. Isso funciona no
user.comments.where(id: avoided_ids_array)
Também para excluir id
Comment.where.not(id: [2, 3, 5])
Para evitar exceções que matam seu aplicativo, você deve pegar essas exceções e tratá -las da maneira que deseja, definindo o comportamento para o seu aplicativo nas situações em que o ID não é encontrado.
begin
current_user.comments.find(ids)
rescue
#do something in case of exception found
end
Aqui está mais informações Sobre exceções em Ruby.
Você também pode usá -lo em nome_scope se quiser colocar as condições de outras pessoas
Por exemplo, inclua algum outro modelo:
nomeado_scope 'get_by_ids', lambda {| ids | {: incluir => [: comentários] ,: condições => ["comentários.id em (?)", ids]}}