Cómo arreglar mi redirección de formulario de modelo anidado

Tengo un proceso de registro que va:

user = User.new
user.email = ...
user.password = ...
user.profile = Profile.new
user.profile.save
user.save

En mi aplicación, inicio el proceso de registro en la página de inicio a través de un InfoController para manejar páginas estáticas. Debido a que el formulario de la página de inicio combina user y profile modelos, estoy usando un formulario de modelo anidado. Sin embargo, cuando envío el formulario, se me redirige al lugar equivocado. ¿Alguien puede ayudarme a descubrir qué hice mal?

Archivo Routes.rb:

match '/login' => "sessions#new", :as => "login"
match '/signup' => 'profiles#new', :as => "signup"
match 'skip/signup', :to => 'info#signupskip'
match 'skip/profiles/new', :to => 'profiles#newskip'

root :to => 'info#home'
root :to => "questions#index"
resources :users
resources :profiles
resources :info
resource :session
resources :session

Controlador de perfiles:

class ProfilesController < ApplicationController
  before_filter :authenticate

  def new
    @profile = Profile.new
  end

  def name
    puts "#{user.profile.first_name} #{user.profile.last_name}"
  end

  def create
    @profile = Profile.new(params[:profile])
    if @profile.save
      redirect_to profile_path, :notice => 'User successfully added.'
    else
      render :action => 'new'
    end
  end
  ...

UsersController:

class UsersController < ApplicationController
  before_filter :authenticate, :only => [:edit, :update]

  def new
    @user = User.new
  end

  def index
    @user = User.all
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to profile_path, :notice => 'User successfully added.'
    else
      render :action => 'new'
    end
  end

Y finalmente, el formulario con modelos anidados:

  <%= form_for(:profile, :url => 'signup', :html => {:id => 'homepage'}) do |f| %>
    <p class="hometext">I'm&nbsp;</p>
    <div>
      <%= f.label :first_name, :placeholder => 'First name' %>
      <%= f.text_field :first_name, :size=> 8, :id => "profile[first_name]" %>
    </div>
    <div>
      <label for="profile[last_name]">Last name</label>
      <%= f.text_field :last_name, :size=> 8, :id => "profile[last_name]" %>
    </div>
    <%= f.fields_for :user do |f| %>
    <p class="hometext">.&nbsp;My&nbsp;email&nbsp;is&nbsp;
      <div>
        <label for="user[email]">Email</label>
        <%= f.text_field :email, :size=> 13, :id => "user[email]" %>
      </div>
    <% end %>
    <p class="hometext">.&nbsp;I want to&nbsp;</p>
    <div>
      <label for="user[goal]">ex: be President</label>
      <%= f.text_field :goal, :size=> 13, :id => "user[goal]" %>
    </div>
    <p class="hometext">when I grow up.&nbsp;</p>
    <div id="button">
      <%= submit_tag 'Join', :class => 'button orange' %>
    </div>
  <% end %>

preguntado el 28 de agosto de 11 a las 03:08

¿No deberías tener un <%= form_for(:user) .. %> y entonces <%= fields_for :profile .. %> ? -

Lo intenté también y, lamentablemente, todavía obtengo la misma redirección. -

Siguiendo con un enlace a una pregunta similar con: usuario primero en el formulario de modelo anidado - stackoverflow.com/questions/7224881/…. ¿Algunas ideas? -

1 Respuestas

La siguiente ruta es incorrecta:

match '/signup' => 'profiles#new', :as => "signup"

En su form_for, estás especificando que es para :profile. Por defecto, Rails POST Esto a profiles#create. Desde que estas pasando :url => 'signup', la forma en realidad está siendo POSTed a /signup, que se asigna, a través de la ruta antes mencionada, a profiles#new. Sin embargo, la new action simplemente configura el formulario, es la acción en la que comenzó. Dicho esto, la ruta correcta debe ser:

match '/signup' => 'profiles#create', :as => "signup"

De hecho, si quisieras hacerlo mucho mejor, debería ser esto:

post '/signup' => 'profiles#create', :as => "signup"

Además, dado que está utilizando una ruta con nombre (pasando as en la ruta), deberías usar :url => signup_path en tu form_for.

Como un comentario rápido: no estoy muy seguro de cómo se ven sus modelos, pero probablemente esté de acuerdo con Kleber aquí. Parece más intuitivo que debería ser form_for :user en vez.

Respondido 31 ago 11, 00:08

¡¡Gracias!! Sí, de hecho me deshice del paso InfoController y ahora tengo form_for: user en el nuevo método UsersController. - tvalent2

Creo que estoy en el camino correcto. Tuve que editar mi before_filter :authenticate en mi ProfilesController. ¡Ups, lo pasé por alto! - tvalent2

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.