0

私はDeviseを使用しており、各ユーザーが1つのプロファイルを作成できるようにしようとしています。新しく登録したユーザーをプロファイルを作成できるページに送ることはできますが、ユーザーがログアウトして再度ログインすると、プロファイル表示ページに移動しません。

言い換えると-

新しいユーザーをサインアップしてユーザーを[プロファイルの作成]ページに送信し、新しいユーザーでプロファイルを作成できます(プロファイルが正しく保存されているかどうかはわかりません)...ログアウトしてサインインした後、受信しましたエラー:

ActiveRecord::RecordNotFound in ProfilesController#show

Couldn't find Profile without an ID

ユーザーをプロフィール表示ページに送信してほしい...

この問題について何か考えはありますか?

コード(ファイルでソート)は以下のとおりです…</ p>

user.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

profile.rb

class Profile < ActiveRecord::Base
 attr_accessible :first_name, :last_name

 belongs_to :user

end

profiles_controller.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

Registrations_controller.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

application_controller.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
4

2 に答える 2

1

コントローラでは、次のコードを使用します@profile = Profile.find(params[:id])。サインインするときはparams[:id]nilでなければなりません。

ここでIDを送信するため、作成後にリダイレクトする場合はnilではありませんredirect_to @profile。これはに変換されredirect_to profile_path(@profile)ます。/ matchパスを使用する場合、IDはありません。

したがって、1つの解決策はcurrent_user、ProfileControllerのshowアクションでヘルパーを使用することです。に置き換え@profile = Profile.find(params[:id])ます@profile = current_user.profile。これにより、ユーザーがサインインする必要があるため、目的の機能が変更される可能性があります。これにより、数学パス(/ show url)が保持されます。IDに依存しなくなったため、機能します。

show_path(resource.profile)または、をに変更することもできますprofile_path(resource.profile)。これは、おそらく探していたshow /の代わりに、URL / profiles /:idを持つリソースプロファイルパスを使用します。

于 2012-09-25T02:14:18.483 に答える
0

@Philの回答で、プロジェクトの別の問題を解決しました。ありがとう\o/

  • ruby 2.0.0p247(2013-06-27リビジョン41674)[x86_64-linux]
  • Rails 4.0.0

そしてあなたの場合、私はこのように解決しました:

ユーザーおよびプロファイルモデルにinverse_of:を追加します。

user.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

profile.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

application_controller.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

これは私のために働きます、私はこれが役立つことを願っています

于 2013-10-31T14:18:49.840 に答える