2015-12-10 5 views
11

Ich habe versucht, diese Post aufzuräumen, damit es nicht so lange für Neulinge scheint. Es enthält Fehler, die sich aus folgenden Vorschlägen von anderen in den Antworten ergeben.Rails 4 - Setup, automatisch Profil erstellen, wenn neuer Benutzer erstellt

Ich versuche, eine App mit Rails 4.

Einfallsreichtum und omniauth verwenden zu machen.

Ich habe Modelle für Benutzer und Profil. Der Benutzer hat ein Profil und das Profil gehört dem Benutzer.

Mein Ziel ist es, das Benutzermodell für alle Dinge zu verwenden, die der Benutzer nicht wirklich berührt. Ich verwende das Profilmodell für Dinge, die der Benutzer verwaltet.

Wenn ein neuer Benutzer erstellt wird, möchte ich, dass der Benutzer zu seiner Profilseite umgeleitet wird, die teilweise mit Details gefüllt sein sollte, die im Benutzermodell erstellt wurden.

Ich habe Probleme.

ich habe:

User.rb

has_one :profile 

Profile.rb

belongs_to :user 

Omniauth_callbacks_controller.rb

if @user.persisted? 
    sign_in_and_redirect_user(:user, authentication.user.profile) 
    set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format? 
else 
    session["devise.#{provider}_data"] = env["omniauth.auth"] 
    redirect_to new_user_registration_url 
end 

ich auch im Rückruf versucht haben umleiten :

sign_in_and_redirect @user, event: :authentication 

Profile/show.html.erb

<div class="container-fluid"> 
    <div class="row"> 
     <div class="col-xs 8 col-xs-offset-1"> 
      <%= @profile.user.formal_name %> 


      <%= @profile.occupation %> 
      <%= @profile.qualification.awards %> 
      <%= @profile.overview %> 
      <%= @profile.research_interests %> 

     </div> 

     <div class="col-xs 3"> 
      <div class="geobox"> 
      <%= render 'addresses/location' %> 
      <%= @profile.working_languages %> 
      <%= @profile.external_profile %> 

      </div> 
     </div> 
    </div> 

    <div class="row"> 
     <div class="col-xs 10 col-xs-offset-1"> 
      <%= render 'profiles/activity' %> 
     </div> 
    </div> 

</div> 

_nav.html.erb

<% if user_signed_in? %> 
        Hi <%= link_to(current_user.first_name.titlecase, profile_path(current_user)) %></span> 

ich auch versucht:

_nav.html.erb

<% if user_signed_in? %> 
        Hi <%= link_to(current_user.first_name.titlecase, user_profile_path(current_user.profile)) %></span> 

Was muss ich tun, um eine Funktion hinzuzufügen, damit ein neuer Benutzer auf seine Profilseite gehen kann?

Momentan, wenn ich versuche, mich einzuloggen und auf den Navigationsleisten-Link zu klicken, möchte ich zur Profilseite gehen. Stattdessen gehe ich zu einer Fehlermeldung, die besagt, dass die von mir gesuchte Seite nicht existiert. Der gesuchte Pfad beginnt mit dem Profil (und nicht mit dem Benutzer/Profil) - nicht sicher, ob das ein Hinweis ist.

Meine Strecken sind:

Profile:

profiles GET  /profiles(.:format)     profiles#index 
         POST  /profiles(.:format)     profiles#create 
      new_profile GET  /profiles/new(.:format)    profiles#new 
      edit_profile GET  /profiles/:id/edit(.:format)   profiles#edit 
       profile GET  /profiles/:id(.:format)    profiles#show 
         PATCH  /profiles/:id(.:format)    profiles#update 
         PUT  /profiles/:id(.:format)    profiles#update 
         DELETE /profiles/:id(.:format)    profiles#destroy 

Benutzer:

user_password POST  /users/password(.:format)    devise/passwords#create 
     new_user_password GET  /users/password/new(.:format)   devise/passwords#new 
     edit_user_password GET  /users/password/edit(.:format)   devise/passwords#edit 
         PATCH  /users/password(.:format)    devise/passwords#update 
         PUT  /users/password(.:format)    devise/passwords#update 
cancel_user_registration GET  /users/cancel(.:format)    users/registrations#cancel 
     user_registration POST  /users(.:format)      users/registrations#create 
    new_user_registration GET  /users/sign_up(.:format)    users/registrations#new 
    edit_user_registration GET  /users/edit(.:format)     users/registrations#edit 
         PATCH  /users(.:format)      users/registrations#update 
         PUT  /users(.:format)      users/registrations#update 
         DELETE /users(.:format)      users/registrations#destroy 
     user_confirmation POST  /users/confirmation(.:format)   devise/confirmations#create 
    new_user_confirmation GET  /users/confirmation/new(.:format)  devise/confirmations#new 
         GET  /users/confirmation(.:format)   devise/confirmations#show 
      user_unlock POST  /users/unlock(.:format)    devise/unlocks#create 
     new_user_unlock GET  /users/unlock/new(.:format)   devise/unlocks#new 
         GET  /users/unlock(.:format)    devise/unlocks#show 
      finish_signup GET|PATCH /users/:id/finish_signup(.:format)  users#finish_signup 

NEW VERSUCH: Weiter unten auf den Vorschlag, verschachtelt ich die Ressourcen wie:

resources :users do 
    resources :profile 
    end 

und ich änderte die Umleitung zu:

def self.provides_callback_for(provider) 
    class_eval %Q{ 
     def #{provider} 
     @user = User.find_for_oauth(env["omniauth.auth"]) 

     if @user.persisted? 
      sign_in_and_redirect [current_user, current_user.profile || current_user.build_profile] 

      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format? 
     else 
      session["devise.#{provider}_data"] = env["omniauth.auth"] 
      redirect_to new_user_registration_url 
     end 
     end 
    } 
    end 

ich diesen Fehler: NoMethodError (nicht definierte Methode `Profil‘ für nil: NilClass):

NÄCHSTE VERSUCH:

ich alle oben halten , sondern versuchen, die Umleitung wie so ersetzen:

def self.provides_callback_for(provider) 
    class_eval %Q{ 
     def #{provider} 
     @user = User.find_for_oauth(env["omniauth.auth"]) 

     if @user.persisted? 
      sign_in_and_redirect [@user, @user.profile || @user.build_profile] 

      set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format? 
     else 
      session["devise.#{provider}_data"] = env["omniauth.auth"] 
      redirect_to new_user_registration_url 
     end 
     end 
    } 
    end 

RuntimeError (Could not find a valid mapping for [#<User id: 1 ... 

und dann listet es alle Attribute in der Benutzertabelle, und dann zeigt:

#<Profile id: nil, user_id: 1, 

gefolgt von allen Attributen in der Profiltabelle.

EIN NEUER VERSUCH

ich diesen Beitrag gefunden: Rails Trying to create a profile after the user has been created

Und ich versuchte, fügte hinzu:

after_create do 
    create_user_profile 
    end 

meinem Benutzermodell.

Ich hielt die Umleitung das gleiche wie ich es hatte (nach Alexei Vorschlag) und versuchte es erneut.

bekomme ich die gleiche Fehlermeldung:

RuntimeError (Could not find a valid mapping for [#<User id: 1 

Jeder kann sehen, wie dieses Problem zu lösen?

Ein weiterer Versuch:

fand ich dann diesen Beitrag: Ruby on Rails - Creating a profile when user is created

die für Rails sagt 4 (was ich), ich brauche diesen Rückruf nur:

after_create: create_profile

Wenn ich dies versuche, bekomme ich den gleichen Fehler wie oben.

eine Idee:

benutzen ich Gerüst Generator für meine Profil-Controller.

Meine Methode erstellen ist:

def create 
    @profile = Profile.new(profile_params) 

    respond_to do |format| 
     if @profile.save 
     format.html { redirect_to @profile } 
     format.json { render :show, status: :created, location: @profile } 
     else 
     format.html { render :new } 
     format.json { render json: @profile.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

Ist dieser Fehler vielleicht etwas mit der Benutzer-ID zu tun, die nicht speziell in diesem Verfahren verwiesen wird. Ich habe user_id in den starken Parametern für den Profil-Controller auf die weiße Liste gesetzt.

EIN NEUER VERSUCH

Dieser Artikel legt nahe, statt create_profile mit build_profile.

https://stackoverflow.com/questions/8337682/create-another-model-upon-user-new-registration-in-devise 

Ich änderte meine user.rb zu

after_create :build_profile 

Wenn ich diese speichern und versuche ich den gleichen Fehler.

ein weiterer Versuch

Antwort Matt in diesem Beitrag schlägt vor, dass ich als eine Definition von build_profile enthalten haben:

after_create :build_profile 

    def build_profile 
    Profile.create(user: self) # Associations must be defined correctly for this syntax, avoids using ID's directly. 
    end 

ich meine user.rb geändert:

after_create :build_profile 

    def build_profile 
    Profile.create(user: self) # Associations must be defined correctly for this syntax, avoids using ID's directly. 
    end 
Wenn Ich speichere und probiere das, ich bekomme einen ähnlichen Fehler, aber mit mehr Informationen. Die Protokolle zeigen nach wie vor:

RuntimeError (Could not find a valid mapping for [#<User id: 1, 

Aber nach all dieser Fehlermeldung, es auf diese neue Information gibt:

SQL (2.9ms) INSERT INTO "profiles" ("user_id", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id" [["user_id", 1], ["created_at", "2015-12-18 21:58:49.993866"], ["updated_at", "2015-12-18 21:58:49.993866"]] 
2015-12-18T21:58:49.966648+00:00 app[web.1]: Profile Load (1.5ms) SELECT "profiles".* FROM "profiles" WHERE "profiles"."user_id" = $1 LIMIT 1 [["user_id", 1]] 
2015-12-18T21:58:50.007428+00:00 app[web.1]: Completed 500 Internal Server Error in 113ms (ActiveRecord: 21.8ms) 
2015-12-18T21:58:49.941385+00:00 app[web.1]: User Load (1.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 1]] 

Hat dieses Angebot irgendein Licht auf das Problem?

UPDATE

Ich versuchte es noch einmal diese (ohne auf den Code irgendwelche Änderungen vorzunehmen). Jetzt bekomme ich einen Fehler, aber dieses Mal der Protokolle sagen:

RuntimeError (Could not find a valid mapping for [#<User id: 1, first_name: "Me", last_name: "Ma", email: "[email protected]", encrypted_password: "$2a$jqQn..HSvlcNtfAH/28.DQoWetO...", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 16, current_sign_in_at: "2015-12-15 09:57:14", last_sign_in_at: "2015-12-15 09:27:07", current_sign_in_ip: #<IPAddr: IPv4:49.191.55>, last_sign_in_ip: #<IPAddr: IPv4:49.191.135.255.255>, confirmation_token: nil, confirmed_at: "2015-12-15 09:02:58", confirmation_sent_at: "2015-12-15 08:42:48", unconfirmed_email: nil, failed_attempts: 0, unlock_token: nil, locked_at: nil, created_at: "2015-12-09 23:53:20", updated_at: "2015-12-15 09:57:14", image: nil>, #<Profile id: 1, user_id: 1, title: nil, hero_image: nil, overview: nil, occupation: nil, external_profile: nil, working_languages: nil, created_at: "2015-12-18 21:58:49", updated_at: "2015-12-18 21:58:49">]): 

Der Unterschied ist diesmal, dass das Profil eine Benutzer-ID-Taste 1 hat Früher war gleich Null.

+0

Wie wird man 'rake routes' suchen Benutzer und Profilpfade? :) – davidwessman

+0

Hallo David, ich kopierte sie über – Mel

+0

"Der Pfad, nach dem es sucht, beginnt am Profil (anstatt Benutzer/Profil) - nicht sicher, ob das ein Hinweis ist." Möchten Sie lieber, dass jeder Benutzer auf ein eindeutiges Profil verweist? Oder möchten Sie 'domain/profile/1' besuchen, um das erste Profil zu erhalten? – davidwessman

Antwort

0

Sie haben sing_in_and_redirect_user in Ihrem Callback-Controller hinzugefügt. Um den Pfad zu bearbeiten, den er an Sie weiterleitet, sollten Sie auch die after_sign_in_path_for in Ihrem applications_controller überschreiben und bearbeiten.

class ApplicationController < ActionController::Base 
    def after_sign_in_path_for(resource) 
    request.env['omniauth.origin'] || stored_location_for(resource) || root_path 
    end 
end 

Hier können Sie den tatsächlichen Pfad zu Redirects bearbeiten. Nicht sicher über den Omniauth Teil, aber Sie könnten profile_path(resource.profile) hinzufügen.

Referenz: https://github.com/plataformatec/devise/wiki/How-To:-redirect-to-a-specific-page-on-successful-sign-in

1

können Sie verschachtelte Ressourcen

resources :users do 
    resource :profile 
end 

und dann

redirect_to [current_user, current_user.profile || current_user.build_profile] 
+0

Hallo - Ich habe das versucht, aber diesen Fehler erhalten: NoMethodError (undefined Methode 'Profil 'für Nil: NilClass): 2015-12-15T10: 33: 09.278064 + 00: 00 App [Web.1] : – Mel

+0

Es sagt Ihnen, dass Sie current_user (current_user == nil) nicht haben. Verwenden Sie @user, wenn es definiert ist. –

+0

Hallo Alexei. Ich benutze ein Gerät. Ich habe den current_user Helfer verfügbar. Sind Sie sicher, dass es um den Benutzer geht, wenn die Methode Profil sagt? Vielen Dank für die Hilfe – Mel