2010-11-02 18 views
117

Estoy utilizando una gema de diseño para los procedimientos sign_in/sign_out.Diseñar formulario dentro de un controlador diferente

que genera archivos vistas desde legado, utilizando rails g devise views

vi que había un archivo Idear/sesiones/new.html.erb que contenía un formulario para sign_in.

Creé otro archivo idear/sessions/_form.html.erb e hice <%= render 'form' %> dentro de un archivo new.html.erb, y funcionó muy bien.

Ahora, quería incluir este formulario desde el controlador diferente. Entonces en un controlador llamado 'main', (específicamente, dentro de la página de visualización) 'mains/index.html.erb' incluí el archivo <%= render 'devise/sessions/form' %>. Parece que la inclusión funcionó bien, pero obtengo el siguiente error.

NameError in Mains#index 

Showing /home/administrator/Ruby/site_v4_ruby/app/views/devise/sessions/_form.html.erb where line #1 raised: 

undefined local variable or method `resource' for #<#<Class:0x007f1aa042d530>:0x007f1aa042b870> 
Extracted source (around line #1): 

1: <%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %> 
2: <p><%= f.label :email %><br /> 
3: <%= f.text_field :email %></p> 
4: 

Parece que form_for (de recursos, ...) parte está causando el problema (que funciona bien si estoy en la página sign_in legado original, ... ¿Cómo puedo resolver este problema en forma de rieles?

yo personalmente prefiero utilizar 'render' función para incluir el formulario, en lugar de escribir códigos hTML en línea.

¿tengo que especificar algo (recurso) dentro del controlador 'principal'?

lo haré agradezco su ayuda. Gracias.

+0

¿Hay alguna solución ...? A fecha de noviembre/16 realmente no tengo la solución usando render ... aunque si solo tecleo el código en línea, funciona bien, parece que ... – user482594

+0

encontraste una solución para esto? – neebz

+0

Sí, elegí la respuesta que resuelve mi problema. Fue más simple de lo que había pensado. – user482594

Respuesta

221

Como dice Andrés, el formulario llama a ayudantes que están especificados por Devise y por lo tanto no están presentes cuando accedes a un formulario Devise desde un controlador que no es Devise.

Para solucionar esto, debe agregar los siguientes métodos a la clase auxiliar del controlador en el que desea mostrar el formulario. De forma alternativa, puede agregarlos a su asistente de aplicaciones para que estén disponibles en cualquier lugar.

def resource_name 
    :user 
    end 

    def resource 
    @resource ||= User.new 
    end 

    def devise_mapping 
    @devise_mapping ||= Devise.mappings[:user] 
    end 

Fuente: http://pupeno.com/blog/show-a-devise-log-in-form-in-another-page/

+8

Finalmente, entiendo todo hoy después de leer esto. – user482594

+5

Excelente. Asegúrate de que va en el helper, no en el controlador. Además, esto podría generar grandes problemas si tiene otros recursos (por ejemplo, empresas que también pueden iniciar sesión) y desea cargar su formulario. Asegúrese de redefinir los nombres, y el enrutamiento también puede convertirse en un problema. –

+1

Lo malo de esta solución es que rompe 'inherited_resources'. – jrhorn424

4

El formulario que creó funciona cuando se representa desde un controlador Devise porque "recurso" se define a través de Devise. Eche un vistazo a la implementación del Devise SessionsController. Por lo que entiendo, está intentando replicar la acción "nueva". El método "build_resource" es probablemente lo que estás buscando.

La gema Warden es el origen de los objetos de "recursos". Si deseas cavar más profundo, ese sería el lugar para mirar.

+0

Acabo de llamar a 'build_resource' en un Mains_controller, pero muestra el error [variable local indefinida o método 'build_resource ']. Traté de incluir idee internal helper insertando 'include Devise :: Controllers :: InternalHelpers' en la parte superior del 'mains_controller', pero también genera un error con 'AbstractController :: ActionNotFound' – user482594

8

puede probar esto también ... question comprobar esto.

Source

<%= form_for("user", :url => user_session_path) do |f| %> 
    <%= f.text_field :email %> 
    <%= f.password_field :password %> 
    <%= f.check_box :remember_me %> 
    <%= f.label :remember_me %> 
    <%= f.submit 'Sign in' %> 
    <%= link_to "Forgot your password?", new_password_path('user') %> 
<% end %> 
+0

¿No es esta la mejor práctica de todas las respuestas? – allegutta

2

que estaba recibiendo el mismo error undefined local variable or method "resource" usted describe de una de mis controladores, porque mi clase base del controlador faltaba la siguiente (carriles-API ActionController :: API tuvo la culpa):

include ActionController::Helpers 

Por lo tanto, los métodos auxiliares de Devise no se pudieron resolver en la vista.

para hacer el trabajo Diseñar con rieles-API que tenía que incluir:

class ApplicationController < ActionController::API 

    include AbstractController::Rendering 
    include AbstractController::Layouts 
    include ActionController::MimeResponds 
    include AbstractController::Translation 
    include ActionController::ImplicitRender 
    include ActionController::Helpers 
2

Para refinar en la respuesta aceptada, utilizamos este helper para permitir diferentes tipos de recursos:

def resource_name 
    @resource_name ||= if admin_controller? 
    :admin_user 
    else 
    :user 
    end 
end 

def resource 
    @resource ||= resource_name.to_s.classify.constantize.new 
end 

def devise_mapping 
    @devise_mapping ||= Devise.mappings[resource_name] 
end 

donde admin_controller? es algo que tenemos desde antes en el ApplicationController para manejar los redireccionamientos de inicio de sesión:

def admin_controller? 
    !devise_controller? and request.path =~ /^\/admin/ 
end 
helper_method :admin_controller? 
Cuestiones relacionadas