terça-feira, 6 de maio de 2008

Undefined method *_path no uso do form_for

Essa é uma dica boba para aqueles que estão começando em ruby on rails como eu. Fazendo aqui um exemplos simples de cadastro de filmes recebi o seguinte erro:
NoMethodError in Filme#incluir

Showing filme/incluir.html.erb where line #5 raised:

undefined method `filmes_path' for #<ActionView::Base:0xb76f144c>

Extracted source (around line #5):

2:
3: <%= error_messages_for :filme %>
4:
5: <% form_for @filme do |f| %>
6: <p>
7: <b>Título</b><br />
8: <%= f.text_field :titulo %>
Pelo que eu entendi até agora, isso acontece porque eu não estou utilizando os métodos padrões do ruby on rails. Se eu estiver falando besteira por favor me corrijam. O fato é que resolvi isso definindo a ação que o form deverá executar, o código da view então ficaria da seguinte forma:
<h1>Incluir novo filme</h1>

<%= error_messages_for :filme %>

<% form_for @filme, :url => { :action => 'salvar' } do |f| %>
<p>
<b>Título</b><br />
<%= f.text_field :titulo %>
</p>

<p>
<b>Resumo</b><br />
<%= f.text_area :resumo %>
</p>

<p>
<%= f.submit "Incluir" %>
</p>
<% end %>
No caso o controlador possui o método salvar.

9 comentários:

  1. Tá programando em Rails agora, Tiago?

    ResponderExcluir
  2. Valeu me ajudou muito. To aprendendo também. Boa sorte

    ResponderExcluir
  3. O que você fez não está errado, mas o rails torna isso até mais fácil amigão. Rails trabalha com 'REST' Representational State Transfer. Quando você define uma entidade, no seu caso 'Filme', você deve definir as url de manipulação dessa entidade (CRUD), para isso você deve ir em config/routes.rb e definir 'map.resources :filmes' isso vai criar as urls de manipulação do elemento (essa q o rails procurou no seu form, mas não encontrou) e no controller você deve definir as actions convencionadas que são (index - listar, show - exibir detalhes do elemento, new - exibe formulário de criação, create - cria o elemento, edit - exibe o formulário de atualização, update - atualiza o elemento e destroy). Essas actions são utilizadas em conjunto com os métodos HTTP específicos (GET para index, new, edit - actions não destrutivas, que não alteral o elemento), (POST para create), (PUT para update) e (DELETE para destroy). esse assunto é muito interessante em rails, aconselho fortemente vc se aprofundar nele dando uma googlada com os termos REST e RAIL, vc vai aprender um bocado. Espero ter ajudado, abraço.

    ResponderExcluir
  4. Olá Tiago,

    valeu pela dica...
    só uma pergunta, por que você está usando os métodos nomeados em português? Isso não está dificultando seu desenvolvimento, por estar "fugindo" dos padrões do Rails?
    O Carlos Brando do nomedojogo.com comentou sobre isso em um dos seus posts, dá uma olhadinha http://www.nomedojogo.com/2009/02/13/rails-way-3-nomes-de-metodos-e-variaveis-devem-ser-obvios/

    Abraços

    ResponderExcluir
  5. você adicionou no arquivo routes.rb a chamada "map.resources :filmes"?
    tente também rodar o comando rake routes no console, para ver as rotas que você já tem.

    Se não me engano, o 'form_for' identifica se o parâmetro passado (no seu caso @filme) é um registro novo, ou já existente, identifica qual o modelo de dados, e faz a chamada da rota.

    similar a este comando "polymorphic_path(@record)"

    ResponderExcluir
  6. @Esdras @Anônimo Quando postei isso ainda estava iniciando o meu estudo em rails, vide data do post (6 de Maio de 2008). Ainda não entendia muito bem como funcionava o routes. De qualquer forma, valeu pela dica, fica aqui registrado para quando outras pessoas tiverem o mesmo problema.

    ResponderExcluir
  7. @Carlos Eu já havia lido esse post do Carlos Brando e inclusive comentei lá sobre o assunto:

    "Sem dúvida programação bilingue pode ficar um pouco confusa, mas para manter a comunicação com o cliente torna tudo mais fácil. Se o seu cliente chama uma fatura de fatura, creio ser mais simples para a comunicação se o nome da classe refletir como é chamada na vida real."

    A resposta dele sobre isso incluia coisas que não eram inerentes à discussão como "manter a equipe de desenvolvimento motivada", então não comentei mais.

    Minha opinião continua a mesma. Já desenvolvi colocando as classes e métodos de domínio em inglês tendo um cliente que falava português. As reuniões ficavam muito confusas uma vez que a empresa contratante falava Cliente, e de vez enquando nós falavámos Customer em nossas reuniões.

    Já em outra ponta, recentemente fiz um plugin pro rails o copy_errors_from, e o fiz totalmente em inglês. Isso porque meu publico alvo era o mundo inteiro.

    ResponderExcluir