Eu vi o código mostrado neste vídeo Go Rails em 05:15: Vídeo-tutorial
<%= form_with model: Link.new do |form| %>
# ...
<% end %>
Normalmente eu teria escrito uma new-action. Algo como:
def new
@link = Link.new
end
Obviamente, é possível pular a ação e criar o objeto necessário imediatamente, ao invocar o form_with.
Qual é o benefício de ter uma nova ação?
É para ter uma rota separada, que cria o formulário, quando invocada?
O método do controlador, estritamente falando, não é realmente necessário, mas sua principal vantagem é que ele coloca a lógica em um lugar claro e coerente.
A visualização é inerentemente confusa, pois é uma combinação de marcação e código e deve realmente se preocupar apenas em transformar os dados fornecidos em HTML da maneira mais direta possível. Instanciar ou consultar esses dados deve ser responsabilidade do controlador.
Essa separação de preocupações se torna mais importante conforme o nível de complexidade cresce. Mas, ao realmente tomar o caminho um pouco mais longo, você evita ter que reescrever o código quando a complexidade cresce.
Além das questões conceituais, também há razões práticas diretas pelas quais essa
<%= form_with model: Link.new do |form| %>
não é uma prática muito boa:Embora você possa lidar com isso na visualização com:
Isso está colocando a lógica em uma visão onde ela não pertence.
Na verdade não, já que isso é possível de qualquer maneira.
Mesmo que você não tenha uma ação de controlador correspondente, o Action Rails procurará implicitamente por uma visualização e a renderizará.
Trata-se mais de separar as preocupações de uma forma que se adapte bem à complexidade e que outros desenvolvedores Rails esperam.
Essencialmente — sim. Se o cliente tiver conhecimento de que tipo de solicitação fazer, ele apenas faz uma solicitação diretamente para
create
a ação e passa os parâmetros corretos. O exemplo seria você testandocreate
viacurl
na linha de comando, ou um cliente REST fazendo as solicitações (outro programador lê os documentos e sabe o que enviar no corpo da solicitação — nenhumanew
chamada necessária).O navegador é um tipo “especial” de cliente, e ele precisa chamar
new
para poder mostrar um formulário ao seu usuário. Eles fazem escolhas com base nos widgets do formulário (digitam coisas em entradas de texto, selecionam opções de selects/radio/checkboxes) e então clicam em submit, o que termina como um POST que aterrissa nacreate
ação.A
Link.new
parte não está comunicando ao seu aplicativo que você está criando um novo objeto. Ele é usado peloform_with
helper e tenta buscar dados para mostrar no seu formulário. (Ele também usa o nome do modelo para descobrir quais devem ser os nomes dos campos, no seu exemplo os campos seriamlink[attribute_name]
). Então passar um objeto (mesmo um vazio, como Link.new) é necessário para que o framework descubra todos os detalhes de que precisa para renderizar o formulário corretamente. E um formulário renderizado corretamente significa executar corretamente a solicitação POST no envio.Geralmente, o fato de você estar criando um novo objeto é comunicado pelo fato de não haver
id
campo. Verifique seus formulários de edição e veja se há umid
campo oculto ali, ou se está na URL de ação do formulário.Para melhor entendimento
Link.new
em seu formulário, faça alguns experimentos. Por exemplo, você pode fazerform_with model: Link.new(foo: "default value")
e do formulário renderizado tentaria mostrar o campo:foo
que teria um “valor padrão” definido. Ou você pode fazerSomeDifferentModel.new
e comparar o formulário HTML resultante.