2013-10-03 62 views
1

我花了一段時間試圖尋找答案來調試。NoMethodError Railscast 250 - Rails 4

我正在關注下面的Railscast 250 (Authentication from scratch),這是針對Rails 3的Rails 4. 很顯然,我認爲我已經使用通常的方法解決了強參數問題。 我目前正在此錯誤:

undefined method `password' for #User:0xb640d880

Extracted source (around line #32): respond_to do |format|

if @user.save 
    format.html { redirect_to @user, notice: 'User was successfully created.' } 
    format.json { render action: 'show', status: :created, location: @user } 
else 

我知道控制器可以訪問密碼屬性,但由於某些原因的模型不能即使我確認存在:密碼在模型中。

user.rb

class User < ActiveRecord::Base 
before_save :encrypt_password 
validates_confirmation_of :password 
validates_presence_of :password, :on => :create 
validates_presence_of :email 
validates_uniqueness_of :email 

def encrypt_password 
    if password.present? 
     self.password_salt = BCrypt::Engine.generate_salt 
     self.password_hash = BCrypt::Engine.hash_secret(password, password_salt) 
    end 
end 
end 

users_controller.rb

class UsersController < ApplicationController 
    before_action :set_user, only: [:show, :edit, :update, :destroy] 

    # GET /users 
    # GET /users.json 
    def index 
    @users = User.all 
    end 

    # GET /users/1 
    # GET /users/1.json 
    def show 
    end 

    # GET /users/new 
    def new 
    @user = User.new 
    end 

    # GET /users/1/edit 
    def edit 
    end 

    # POST /users 
    # POST /users.json 
    def create 
    logger.warn user_params[:password] 
    @user = User.new(email: user_params[:email], password_hash: user_params[:password_hash], password_salt: user_params[:password_salt]) 

respond_to do |format| 
    if @user.save 
    format.html { redirect_to @user, notice: 'User was successfully created.' } 
    format.json { render action: 'show', status: :created, location: @user } 
    else 
    format.html { render action: 'new' } 
    format.json { render json: @user.errors, status: :unprocessable_entity } 
    end 
end 
    end 

    # PATCH/PUT /users/1 
    # PATCH/PUT /users/1.json 
    def update 
     respond_to do |format| 
      if @user.update(user_params) 
      format.html { redirect_to @user, notice: 'User was successfully updated.' } 
      format.json { head :no_content } 
      else 
      format.html { render action: 'edit' } 
      format.json { render json: @user.errors, status: :unprocessable_entity } 
      end 
     end 
    end 

    # DELETE /users/1 
    # DELETE /users/1.json 
def destroy 
    @user.destroy 
    respond_to do |format| 
     format.html { redirect_to users_url } 
     format.json { head :no_content } 
    end 
    end 
    private 

    # Use callbacks to share common setup or constraints between actions. 
    def set_user 
     @user = User.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def user_params 
     params.require(:user).permit(:email, :password_hash, :password_salt, :password) 
    end 
end 

_form.html.erb(視圖)

<%= form_for(@user) do |f| %> 
    <% if @user.errors.any? %> 
     <div id="error_explanation"> 
     <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> 

     <ul> 
    <% @user.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
    <% end %> 
    </ul> 
    </div> 
<% end %> 

<div class="field"> 
    <%= f.label :email %><br> 
    <%= f.text_field :email %> 
</div> 
<div class="field"> 
    <%= f.label :password %><br> 
    <%= f.password_field :password %> 
</div> 
<div class="field"> 
    <%= f.label :password %><br> 
    <%= f.password_field :password %> 
</div> 
<div class="actions"> 
    <%= f.submit %> 
</div> 
    <% end %> 

釷爲你的幫助!

+0

我認爲你有一個password_hash列在表中,並在params使用密碼,這就是爲什麼你會得到一個錯誤 –

+0

請發佈您的遷移文件 –

+0

感謝您的答覆阿米特,我知道我沒有在我的表中的密碼。我如何排除保存到表中的密碼?但同時我想讓密碼可以被MCV訪問? 對不起,如果我原來的問題模糊:) – par

回答

1

我已經創建了一個用戶認證示例項目,請檢查它。

Users_controller.rb

class UsersController < ApplicationController 

    def new 
    @user = User.new 
    end 

    def create 

    @user = User.new(user_params) 
    #raise params.inspect 
    if @user.save 
     redirect_to root_url, :notice => "Signed up!" 
    else 
     render "new" 
    end 
    end 

    private 
    def user_params 
    params.require(:user).permit(:email, :password_hash, :password_salt, :password) 
    end 

end 

new.html.erb

<h1>Sign Up</h1> 

<%= form_for @user do |f| %> 
    <% if @user.errors.any? %> 
    <div class="error_messages"> 
     <h2>Form is invalid</h2> 
     <ul> 
     <% for message in @user.errors.full_messages %> 
      <li><%= message %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 
    <p> 
    <%= f.label :email %><br /> 
    <%= f.text_field :email %> 
    </p> 
    <p> 
    <%= f.label :password %><br /> 
    <%= f.password_field :password %> 
    </p> 
    <p> 
    <%= f.label :password_confirmation %> 
    <%= f.password_field :password_confirmation %> 
    </p> 
    <p class="button"><%= f.submit %></p> 
<% end %> 

user.rb

class User < ActiveRecord::Base 
    attr_accessor :password 
    before_save :encrypt_password 


    validates_confirmation_of :password 
    #validates_presence_of :password, :on => :create 
    validates_presence_of :email 
    validates_uniqueness_of :email 

    def encrypt_password 
    #raise password.inspect 
    if password.present? 
     self.password_salt = BCrypt::Engine.generate_salt 
     self.password_hash = BCrypt::Engine.hash_secret(password, password_salt) 
    end 
    end 
end 

以上代碼工作正常。

0

您的模型缺少密碼的attr_accessor。由於您的表中沒有密碼列,但仍然需要接收密碼屬性(因此您可以使用鹽處理它,然後將其變爲散列),您需要擁有此訪問器。

在您的用戶模型補充一點:

attr_accessor :password 

編輯:就像阿米特·夏爾馬在他的演示中指出。