2011-11-01 25 views
0

我有一個用於更新某些屬性的編輯表單。但它試圖編輯所有的屬性,並導致我有驗證錯誤。如何在rails中只更新一部分屬性,不是全部

我的形式(編輯視圖)

#person_info.fl_l 
    - if @user.errors.any? 
    .error_explanation 
     %h2 Form is invalid 
     %ul 
     -for message in @user.errors.full_messages 
      %li= message 


    =form_for @user do |f| 
    %p 
     Birthday: 
     %br 
     = f.date_select(:birthday,:start_year => 1940) 
    %p 
     Name: 
     %br 
     = f.text_field :name, :value=>@user.name 
    %p 
     Surname: 
     %br 
     = f.text_field :surname, :value=>@user.surname 
    %p 
     Nickname: 
     %br 
     = f.text_field :nickname, :value=>@user.surname  
    %p 
     About Myself: 
     %br 
     = f.text_area :about_myself, :value=>@user.about_myself 
    %p 
     = f.submit "Update" 

我的更新和編輯的操作:

def edit 
     @user = User.find(params[:id]) 
    end 

    def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(params[:user]) 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end 

當我提交表單,它輸出像驗證錯誤:「密碼不能爲空」

那麼,如何只更新一部分屬性,不是全部?我不想在我的情況下更新密碼。

我的用戶模型

class User < ActiveRecord::Base 

    has_many :posts 
    has_many :sent_messages, :class_name => "Message", :foreign_key => "sender_id" 
    has_many :received_messages, :class_name => "Message", :foreign_key => "receiver_id" 
    attr_accessible :name, :email, :password, :password_confirmation 
    has_secure_password 
    email_regex = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i 

    validates :name, :presence => true, 
      :length => {:maximum => 50} 
    validates :email, :presence => true, 
      :format => {:with => email_regex}, 
      :uniqueness => {:case_sensitive => false} 

    validates :password, :presence => true, 
      :confirmation => true, 
      :length => {:within => 6..40} 


    before_create { generate_token(:auth_token) } 

    def send_password_reset 
    generate_token(:password_reset_token) 
    self.password_reset_sent_at = Time.zone.now 
    save! 
    UserMailer.password_reset(self).deliver 
    end 

    def generate_token(column) 
    begin 
     self[column] = SecureRandom.urlsafe_base64 
    end while User.exists?(column => self[column]) 
    end 
end 
+0

你能解決這個問題嗎?我有完全相同的問題:S – Cas

回答

0

我相信你的模型在當前狀態下是無效的......你沒有發送密碼,所以Rails沒有觸及那個屬性。

在軌控制檯,測試:

user = User.find(whatever_the_id_is) 
puts user.valid? 
puts user.errors.inspect 

我的假設是,它是無效的---因爲缺少一個密碼。

+0

我添加用戶模型到 – Pavel

+0

問題是的,它是無效的,但它是怎麼回事?因爲在我的註冊表單中工作正常,並且它有密碼輸入 – Pavel

+0

如果模型是在添加密碼屬性之前創建的,那麼它將是無效的,但新模型將是有效的。 –

0

從params哈希表

params.delete(:password) 

移除或建立自己的散列發送更新。

+0

我已經添加params.delete(:密碼)更新操作,但它沒有工作,我有密碼存在驗證,並且它輸出我錯誤 – Pavel

+0

「或者構建您自己的散列以發送更新「。我是新手,donk知道如何使它在我的情況下( – Pavel

0

我已經在用戶密碼驗證解決了這個像這樣:

validates :password, :presence  => true, 
        :confirmation => true, 
        :if   => :password # only validate if password changed! 
+0

哎呀,只是發現這不會解決你的問題,如果單獨這樣,因爲你可以最終更新你的密碼而無需驗證!我添加了一個attr_accessible密碼使它只適用於:create和:update_password。如果你正在考慮這樣做 - 或者只是結合我的和@ mb14的回答 – emrass

+0

「我添加了一個attr_accessible密碼,以使其僅適用於:創建和:update_password「你能解釋如何做到這一點嗎? – Pavel

+0

結合你的和mb14的答案不會輸出錯誤,但它沒有保存更改。 – Pavel

1

結帳Authentication in Rails 3.1更加順暢出您的身份驗證。它會從你的模型中取出很多代碼。

然後,我注意到:如果某個字段由於任何原因而從表單中隱藏起來,那麼rails不會在params散列中傳遞此更新。所以你可以玩在窗體中隱藏字段。這是我解決我的問題。

1

我通過附加

,:on => :create 

我validates_presence_of和validates_length_of線修復了這個問題。

+0

這是你想要的,如果你不想傳遞密碼來更新屬性。 –