Mecanizar definir um campo com um nome duplicado
-
13-09-2019 - |
Pergunta
Eu estou usando mecanizar e ter um problema em uma forma ... o formulário tem duas caixas de seleção com o mesmo nome.
Como posso seleccionar o segundo?
ie. NumNights segunda ocorrência.
i encontrados no docs algo como isto:
form.set_fields( :foo => ['bar', 1] )
mas isso não funcionou:
form.field_with(:name => [ 'NumNights', 2 ]).options[no_days.to_i-1].select
Solução
Obter uma referência a um formulário, e iterar sobre os membros. Algo parecido com isto:
my_fields = form.fields.select {|f| f.name == "whatever"}
my_fields[1].whatever = "value"
Depois que você terminar de preencher os formulários, apresentá-lo. Eu não corri este código, mas acho que ele deve funcionar.
Outras dicas
Geo tem uma solução decente, mas há algumas oportunidades perdidas lá.
Se você está encontrando apenas um elemento, é provavelmente mais eficiente usar Enumerable # encontrar em vez de Enumerable # selecionar e, em seguida, Array # primeiro em cima disso. Alternativamente, você pode simplesmente fazer a reatribuição durante a seleção.
Se você olhar para a abordagem sugerida há uma chance de você acionar uma exceção se um campo com esse nome não for encontrada:
# Original approach
my_fields = form.fields.select {|f| f.name == "whatever"}
# Chance of exception here, calling nil#whatever=
my_fields[1].whatever = "value"
Eu defendo usando Enumerable # selecionar e simplesmente fazer o trabalho dentro do loop, muito mais seguro assim:
my_fields = form.fields.select do |f|
if (f.name == "whatever")
# Will only ever trigger if an element is found,
# also works if more than one field has same name.
f.whatever = 'value'
end
end
A outra abordagem é usar Enumerable # find que retorna no máximo um elemento:
# Finds only a single element
whatever_field = form.fields.find { |f| f.name == "whatever" }
whatever_field and whatever_field.whatever = 'value'
Claro que você pode sempre pimenta seu código com capturas de exceção, mas que parece contraproducente.