代码之家  ›  专栏  ›  技术社区  ›  JLBaguio

将用户(设备)连接到其配置文件

  •  0
  • JLBaguio  · 技术社区  · 12 年前

    我正在使用Devise,并试图允许每个用户创建1个配置文件。我可以将新注册的用户发送到他们可以创建配置文件的页面,但一旦用户注销并重新登录,就不会转到配置文件显示页面。

    换句话说-

    我可以注册一个新用户并将该用户发送到“创建配置文件”页面,然后我可以与新用户一起创建配置文件(我不确定配置文件是否正确保存)。。。注销并登录后,我收到错误:

    ActiveRecord::RecordNotFound in ProfilesController#show
    
    Couldn't find Profile without an ID
    

    我希望用户被发送到他们的个人资料显示页面。。。

    对这个问题有什么想法吗?

    代码(按文件排序)如下

    用户.rb

    class User < ActiveRecord::Base
      devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
    
      attr_accessible :email, :password, :password_confirmation, :remember_me
    
     has_one :profile
    end
    

    个人资料.rb

    class Profile < ActiveRecord::Base
     attr_accessible :first_name, :last_name
    
     belongs_to :user
    
    end
    

    配置文件_控制器.rb

    class ProfilesController < ApplicationController
     # GET /profiles
     # GET /profiles.json
    def index
     @profiles = Profile.all
    
    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @profiles }
     end
    end
    
    # GET /profiles/1
    # GET /profiles/1.json
    def show
     @profile = Profile.find(params[:id])
    
     respond_to do |format|
      format.html # show.html.erb
      format.json { render json: @profile }
     end
    end
    
    # GET /profiles/new
    # GET /profiles/new.json
    def new
     @profile = Profile.new
    
     respond_to do |format|
      format.html # new.html.erb
      format.json { render json: @profile }
     end
    end
    
    # GET /profiles/1/edit
    def edit
     @profile = Profile.find(params[:id])
    end
    
    # POST /profiles
    # POST /profiles.json
    def create
      @profile = Profile.new(params[:profile])
    
    respond_to do |format|
      if @profile.save
        format.html { redirect_to @profile, notice: 'Profile was successfully created.' }
        format.json { render json: @profile, status: :created, location: @profile }
      else
        format.html { render action: "new" }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
     end
    end
    
    # PUT /profiles/1
    # PUT /profiles/1.json
    def update
     @profile = Profile.find(params[:id])
    
     respond_to do |format|
       if @profile.update_attributes(params[:profile])
         format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
         format.json { head :no_content }
       else
         format.html { render action: "edit" }
         format.json { render json: @profile.errors, status: :unprocessable_entity }
       end
     end
    end
    
    # DELETE /profiles/1
    # DELETE /profiles/1.json
    def destroy
      @profile = Profile.find(params[:id])
      @profile.destroy
    
      respond_to do |format|
        format.html { redirect_to profiles_url }
        format.json { head :no_content }
      end
     end
    end
    

    注册控制器.rb

    class RegistrationsController < Devise::RegistrationsController
      protected
    
      def after_sign_up_path_for(resource)
        request.env['omniauth.origin'] || stored_location_for(resource) || new_profile_path
      end
    end
    

    应用程序控制程序.rb

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

    路线.rb

    BaseApp::Application.routes.draw do
      resources :profiles
    
      get "users/show"
    
      devise_for :users, :controllers => { :registrations => "registrations" }
      resources :users
    
      match '/show', to: 'profiles#show'
    
    
      match '/signup',  to: 'users#new'
    
      root to: 'static_pages#home'
    
      match '/', to: 'static_pages#home'
    
      …
    end
    
    2 回复  |  直到 12 年前
        1
  •  1
  •   Phil Dudley    12 年前

    在控制器中,您使用以下代码 @profile = Profile.find(params[:id]) .登录时 params[:id] 必须为零。

    当你在创建后重定向时,它不是零,因为你在这里发送了一个id redirect_to @profile 。这意味着 redirect_to profile_path(@profile) 。当您使用/match路径时,没有id。

    因此,一个解决方案是使用helper current_user 在ProfileController的显示操作中。代替 @profile=profile.fund(params[:id]) 具有 @profile = current_user.profile 。这可能会更改您所需的功能,因为它需要用户登录。这将保留数学路径(/show-url)。它之所以有效,是因为它不再依赖于id。

    您也可以更改 show_path(resource.profile) profile_path(resource.profile) 。这将使用带有url/profiles/:id的resources profiles路径,而不是您可能要查找的show/。

        2
  •  0
  •   Herbert Hudson    11 年前

    通过@Phil提供的答案,我解决了项目中的另一个问题。谢谢/

    • ruby 2.0.0p247(2013-06-27修订版41674)[x86_64-linux]
    • 轨道4.0.0

    而你的案子,我是这样解决的:

    在用户和配置文件模型中添加inverse_of::

    用户.rb

    class User < ActiveRecord::Base
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
           :recoverable, :rememberable, :trackable, :validatable
    
      has_one :profile, inverse_of: :user
    end
    

    个人资料.rb

    class Profile < ActiveRecord::Base
      belongs_to :user, inverse_of: :profile
      validates :first_name, :user_id, :presence => true
      validates :gender, :inclusion => {:in => %w(M F)}
    
    end
    

    在您的 应用程序控制程序.rb

    class ApplicationController < ActionController::Base
      # Prevent CSRF attacks by raising an exception.
      # For APIs, you may want to use :null_session instead.
      protect_from_forgery with: :exception
    
      # redirect user after login
      def after_sign_in_path_for(resource)
        unless current_user.profile.nil?
          profiles_path 
        else
          flash[:alert] = "Please complete your profile"
          new_profile_path
        end
      end
    
      # redirect after logout
      def after_sign_out_path_for(resource_or_scope)
        new_user_session_path
      end
    
    end
    

    这对我有用,我希望这能有所帮助