2014-06-09 53 views
1

在我的Rails應用的帳戶設置頁面上,我嘗試使用Ajax在更新表單提交後更新顯示的用戶設置信息。現在,當我提交表單時,數據庫得到更新並且_account_settings.html.erb部分似乎被重新呈現,但部分不顯示更新的信息。例如,假設用戶名是「John Doe」,並且他點擊了「#edit_name」鏈接。這呈現了他可以用來更改他的名字的_name_form.html.erb。當他更改姓名並提交表單時,假設他將其更改爲「Joe Blow」,表單消失,並且「姓名:<%= current_user.name%> - 單擊編輯」再次顯示,但名稱仍然存在「John Doe」,儘管DB中的名字現在是「Joe Blow」。如果我刷新頁面,名稱現在顯示爲「Joe Blow」。我正在使用設計並製作了一個自定義註冊控制器,以允許用戶在不輸入密碼的情況下更新某些屬性(名稱仍需要當前密碼)。我用this code provided by the devise和簡單地添加Rails 4 - 部分呈現update.js.erb未顯示更新的值

respond_to do |format| 
    format.html { redirect_to edit_user_registration_path } 
    format.js 
end 

的「如果@ user.update_attributes(account_update_params)」在上面的鏈接塊的末尾。關於爲什麼重新渲染的部分不顯示更新的用戶信息的任何想法?

edit.html.erb 
<h1>Account Settings</h1> 
<div id="account_settings_container"> 
    <%= render 'account_settings' %> 
</div> 


_account_settings.html.erb 
<div class="user-attribute-container"> 
    <%= link_to "#", class: "edit-attribute", id: "edit_name", remote: true do %> 
     <p>Name: <%= current_user.name %> - click to edit</p> 
    <% end %> 
</div> 

<div class="user-attribute-container"> 
    <%= link_to "#", class: "edit-attribute", id: "edit_email", remote: true do %> 
     <p>Email: <%= current_user.email %> - click to edit</p> 
    <% end %> 
</div> 

<div class="user-attribute-container"> 
    <%= link_to "#", class: "edit-attribute", id: "edit_password", remote: true do %> 
     <p>Password: click to edit your password</p> 
    <% end %> 
</div> 

<%= javascript_tag do %> 
    $("#edit_name").click(function() { 
     $(this).hide().after("<%= escape_javascript(render('name_form')) %>"); 
    }); 
    $("#edit_email").click(function() { 
     $(this).hide().after("<%= escape_javascript(render('email_form')) %>"); 
    }); 
    $("#edit_password").click(function() { 
     $(this).hide().after("<%= escape_javascript(render('password_form')) %>"); 
    }); 
<% end %> 


_name_form.html.erb (the email and password form partials have :email, :password & :password_confirmation instead of :name, otherwise they're the same) 
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name), :method => :put, :html => { id: "edit_user_name" }, remote: true) do |f| %> 
    <%= f.label :name, "Name" %> 
    <%= f.text_field :name %> 

    <%= f.label :password_field, "Password" %> 
    <%= f.password_field :current_password %> 

    <%= f.submit "Update" %> 
<% end %> 


update.js.erb 
$("#account_settings_container").html("<%= escape_javascript(render('account_settings')) %>"); 

從日誌文件:

Started PUT "/users" for 127.0.0.1 at 2014-06-09 15:01:21 -0700<br> 
Processing by RegistrationsController#update as JS<br> 
    Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Joe Blow", "current_password"=>"[FILTERED]"}, "commit"=>"Update"}<br> 
    [1m[36mUser Load (0.0ms)[0m [1mSELECT "users".* FROM "users" WHERE "users"."id" = 14 ORDER BY "users"."id" ASC LIMIT 1[0m<br> 
    [1m[35mUser Load (0.0ms)[0m SELECT "users".* FROM "users" WHERE "users"."id" = $1 LIMIT 1 [["id", 14]]<br> 
    [1m[36m (0.0ms)[0m [1mBEGIN[0m<br> 
    [1m[35mSQL (0.0ms)[0m UPDATE "users" SET "name" = $1, "updated_at" = $2 WHERE "users"."id" = 14 [["name", "Joe Blow"], ["updated_at", Mon, 09 Jun 2014 15:01:21 PDT -07:00]]<br> 
    [1m[36m (0.0ms)[0m [1mCOMMIT[0m<br> 
    Rendered registrations/_name_form.html.erb (15.6ms)<br> 
    Rendered registrations/_email_form.html.erb (0.0ms)<br> 
    Rendered registrations/_password_form.html.erb (15.6ms)<br> 
    Rendered registrations/_account_settings.html.erb (46.9ms)<br> 
    Rendered registrations/update.js.erb (46.9ms)<br> 
Completed 200 OK in 219ms (Views: 78.1ms | ActiveRecord: 0.0ms) 

自定義設計的註冊控制器:通過設計使用的before_filter產生

class RegistrationsController < Devise::RegistrationsController 

    def update 
     @user = User.find(current_user.id) 

     successfully_updated = if needs_password?(@user, params) 
      @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) 
     else 
      # remove the virtual current_password attribute 
      # update_without_password doesn't know how to ignore it 
      params[:user].delete(:current_password) 
      @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) 
     end 

     if successfully_updated 
      # sign_in @user, :bypass => true 
      respond_to do |format| 
       format.html { redirect_to edit_user_registration_path } 
       format.js 
      end 
     else 
      respond_to do |format| 
       format.html { render "edit" } 
       format.js 
      end 
     end 
    end 

    private 

    def needs_password?(user, params) 
     user.email != params[:user][:email] || params[:user][:password].present? || user.name != params[:user][:name] 
    end 
end 
+0

我會嘗試'@ user.update_attributes(account_update_params)'本身,然後你如果塊可能是'如果@ user.save ...'。我認爲正在發生的事情是您的更改被保存到數據庫,但直到方法執行完成後才執行,其中包括部分的重新部署。 –

+0

registrations/update.js.erb是什麼樣的? – Swards

+0

這似乎並沒有解決它。我注意到的一件事是,點擊更新後,'

名稱:<%= current_user.name%> - 點擊以編輯

_account_settings.html.erb的部分具有舊名稱,但名稱輸入標記的值來自同一部分中的JavaScript標記具有更新的名稱。 –

回答

1

CURRENT_USER。因此,返回的對象將是調用該操作方法之前的用戶。您需要使用@user對象,該對象是由操作方法修改的用戶對象。

因此,例如:

<p>Name: <%= @user.name %> - click to edit</p> 
+0

修復它!謝謝! –

+0

參與自鳴得意的模式 – ReggieB