2010-05-19 4 views
1

Donc je travaille avec authlogic, et j'essaye de dupliquer la fonctionnalité de connexion à la page d'accueil, afin que vous puissiez vous connecter par une URL reposante ou en allant simplement à la page principale. Non, je ne sais pas si nous garderons cette fonctionnalité, mais je veux la tester quand même. Voici le message d'erreur:Rails: fonctionnalité en double entre les contrôleurs? Un humble plaidoyer

RuntimeError in Welcome#index Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

Le code est ci-dessous. Fondamentalement, ce qui se passe est la vue d'index (le premier extrait de code) envoie les informations du formulaire à la méthode de création du contrôleur user_sessions. À ce stade, en théorie, il devrait simplement reprendre, mais ce n'est pas le cas.

S'IL VOUS PLAÎT aider. S'il vous plaît. Je fais cela depuis environ 8 heures. J'ai vérifié Google. J'ai vérifié IRC. J'ai vérifié tous les livres que j'ai pu trouver. Vous n'avez même pas à répondre, je peux au travail grunt si vous me pointez juste dans la bonne direction.

=== EDIT EDIT EDIT ===

Sameera était assez bon pour fournir la réponse au problème. Question ouverte, mais est ce que la meilleure façon d'organiser l'application est. Est-ce que l'application de l'objet @user_sessions dans un before_filter est acceptable, ou y a-t-il une façon plus précise de le faire?

BIENVENUE # INDEX

<% form_for @user_session, :url => user_sessions_path do |f| %> 
    <%= f.text_field :email %><br /> 
<%= f.password_field :password %> 
<%= submit_tag 'Login' %> 
<% end %> 

APPLICATION CONTRÔLEUR

class ApplicationController < ActionController::Base 
    helper :all # include all helpers, all the time 
    protect_from_forgery # See ActionController::RequestForgeryProtection for details 
    # Scrub sensitive parameters from your log 
    # filter_parameter_logging :password 
    helper_method :current_user_session, :current_user 
    before_filter :new_session_object 
protected 
    def new_session_object 
     unless current_user 
     @user_session = UserSession.new(params[:user_session]) 
    end 
end 
private 
def current_user_session 
    return @current_user_session if defined?(@current_user_session) 
    @current_user_session = UserSession.find 
end 
def current_user 
    return @current_user if defined?(@current_user) 
    @current_user = current_user_session && current_user_session.record 
end 
end<pre></code> 

SESSIONS UTILISATEUR CONTRÔLEUR

class UserSessionsController < ApplicationController 
    def new 
    @user_session = UserSession.new 
    end 

    def create 
    @user_session = UserSession.new(params[:user_session]) 
    if @user_session.save 
     flash[:notice] = "Logged in" 
     redirect_to root_url 
    else 
     render :controller => 'user_sessions', :action => 'new' 
    end 
    end 

    def destroy 
    @user_session = UserSession.find 
    @user_session.destroy 
    flash[:notice] = "Logged out" 
    redirect_to root_url 
    end 
end 

EMPILEMENT plus détaillée TRACE

1: <h1>Welcome#index</h1> 
2: <p>Find me in app/views/welcome/index.html.erb</p> 
3: 
4: <% form_for @user_session, :url => user_sessions_path do |f| %> 
5: <%= f.text_field :email %><br /> 
6:  <%= f.password_field :password %> 
7: <%= submit_tag 'Login' %> 

Application Trace | Framework Trace | Full Trace 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpac -2.3.5/lib/action_controller/record_identifier.rb:76:in `dom_id' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/record_identification_helper.rb:16:in `dom_id' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:293:in `apply_form_for_options!' 
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:277:in `form_for' 
/Users/alex/Desktop/anglic/app/views/welcome/index.html.erb:4:in `_run_erb_app47views47welcome47index46html46erb' 
+0

S'il vous plaît poster le code pour l'index Bienvenue #. Une trace de pile plus détaillée n'est peut-être pas une mauvaise idée non plus. – jdl

+0

C'était en fait le premier extrait de code, mais je peux voir comment cela ne serait pas clair. – Alex

Répondre

0

Essayez ceci:

form_for :user_session, @user_session, :url => user_session_path(@user_session)} do |f| 

end 
+0

WOOO! ÇA MARCHE! Sameera, monsieur (ou madame!), Vous êtes une personne incroyable et belle. Veuillez accepter mes remerciements les plus sincères et les plus bruyants. Je te donne des droits à mon premier-né. Que tous les dieux du ciel vous remplissent d'argent et de gloire. – Alex

+0

Salut, Ravi de vous voir trouvé ma réponse utile: D acclamations, Sameera – sameera207

+0

Salut Alex, je suis arrivé cet exemple à partir d'exemples de vue de l'action. (/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_view/helpers/form_helper ) Si possible, essayez d'utiliser netbeans (j'utilise 6.9) et cela donne un code automatique et des exemples que vous tapez Je pense que c'est un grand IDE acclamations, – sameera207

0

Je pense que vous pouvez essayer dans votre WelcomeController

class WelcomeController < ActionController::Base 

    def index 
    @user_session = UserSession.new 
    ..... 
    end 

    ..... 

end 

Il me semble que vous essayez d'utiliser @user_session qui n'est pas définie dans la vue de l'action de l'indice WelcomeController.

Espérons que cela aide.

EDIT # 1

Il me semble que le problème se produit lorsque le before_filter a été appelé, après avoir soumis le formulaire dans l'action de l'indice WelcomeController de #.

Cette section de code particulier moi est étrange

class ApplicationController < ActionController::Base 

    ..... 
    private 
    def current_user_session 
    return @current_user_session if defined?(@current_user_session) 
    @current_user_session = UserSession.find 
    end 
    ..... 

end 

Je suis tout à fait sûr UserSession.find cassera.

Espérons que cette édition aide.

EDIT # 2

Une autre chose que je trouve étrange est à l'intérieur de la méthode protégée new_session_object:

protected 
    def new_session_object 
     unless current_user 
     @user_session = UserSession.new(params[:user_session]) 
    end 
end 

Toute la raison pour laquelle UserSession.new a été créé avec params[:user_session]?

Le flux pour votre UserSessionController connexion pour autant que je comprends est:

  1. before_filter :new_session_object est appelé

  2. il retournera false pour current_user car il est une nouvelle session utilisateur

  3. il va définir @user_session variables à UserSession.new(params[:user_session]) valeur

  4. UserSessionController#new l'action est appelée qui override @user_session variable UserSession.new

  5. new.html.erb est rendu contenant le formulaire de connexion

  6. before_filter :new_session_object is appelé à nouveau

  7. il retournera false pour current_user car il est encore une nouvelle session utilisateur

  8. il sera mis en @user_session variables à UserSession.new(params[:user_session]) valeur

  9. UserSessionController#create action est appelée qui sera à nouveau définir la variable @user_session sur UserSession.new(params[:user_session]) valeur.

  10. @user_session est enregistré et la session utilisateur est avec succès créé

mais pour le WelcomeController il est subtilement différent à l'étape 4

La valeur de la variable @user_session qui est utilisée dans la WelcomeController#index provenait de l'affectation de variable d'appel before_filter de UserSession.new(params[:user_session]), à ce moment le params[:user_session] valeur est nil, de sorte que le @user_session = UserSession.new(nil) lorsque le i ndex.html.erb a été rendue.

Je ne suis pas tout à fait sûr que ce soit la chose qui cause votre problème, mais il peut vous aider à résoudre ce problème si vous exécutez script/server --debugger et l'étape Trough la création de @user_session lors de l'utilisation WelcomeController, spécialement lorsque le formulaire est présenté de façon à UserSessionController#create.

+0

Merci pour la réponse! Deux choses. Tout d'abord, ce n'est pas que le formulaire ne charge pas (le before_filter dans l'appcontroller rend cette variable d'instance pour nous), c'est que lorsque nous soumettons la commande, @user_session devrait se propager de Welcome # index à UserSessions # create. Au lieu de cela, nous obtenons l'erreur ci-dessus. Et en second lieu, je détesterais copier le code dans le UserSessionsController acutal, qui fait exactement ce que votre code indique. Y at-il un moyen de faire est que je peux simplement appeler la version de UserSessionsController de nouveau à la place? Merci encore pour la réponse. – Alex

+0

Jetez un oeil à la réponse éditée –

+0

Merci encore une fois pour la réponse! Donc ma question serait alors, pourquoi ne casse-t-il pas si j'émets un POST: créer à partir du contrôleur UserSessions? La seule fois où je reçois cette erreur est quand j'essaie de POST: créer à partir d'un contrôleur différent. De plus, c'est une méthode interne qu'Authlogic a besoin de gérer des sessions, et je pense qu'elle est exécutée au moins une fois par requête. Je m'attendrais donc à ce que l'erreur se manifeste plus qu'elle ne l'a été, bien que je puisse me tromper à ce sujet. – Alex

1

Vous devez ajouter la méthode suivante à la ApplicationController:

def require_user 
    unless current_user 
     flash[:notice] = "You must be logged in to access this page!" 
     redirect_to :controller => "user_sessions", :action => "new"    
     return false 
    end 
end 

Ensuite, dans le WelcomeController ajouter un avant filtre comme ceci:

before_filter :require_user 

Maintenant, tout le monde l'accès à WelcomeController seront redirigés vers la connexion page. Vous n'avez pas à dupliquer la fonctionnalité entre les contrôleurs.

S'il vous plaît passer par le tutoriel set-up Authlogic pour plus de détails: http://rdoc.info/projects/binarylogic/authlogic

+0

Salut, Syed. Désolé, ne pas être difficile, mais chaque once de travail que vous causez aux utilisateurs est une autre excuse pour eux de quitter le site complètement. Ce n'est pas que je ne sais pas je ne peux pas before_filter les utilisateurs, c'est que je ne le veux franchement pas. – Alex

+0

Aussi, merci pour le site, mais je l'ai en fait parcouru. Mon système d'authentification, par exemple, est hautement personnalisé. De plus, je ne rêverais pas de déranger les gens de SO à moins que je n'eusse épuisé toutes les solutions à ma disposition. – Alex

Questions connexes