如何使用Devise使用Ajax更新用户?

时间:2016-06-12 21:42:54

标签: ruby-on-rails ajax forms ruby-on-rails-4 devise

我已经在这里搜索了所有内容,但我能找到的所有内容都是#34; 如何使用Ajise使用Ajax登录用户"。我想要的是" 如何使用Devise "正确更新用户的方式。

到目前为止,我已经设法通过Ajax成功更新用户。但是,如果有错误,那些错误将无法显示。这是我需要帮助的地方。

以下是表单现在的样子:

enter image description here

以下是与此设计形式相关的文件:

视图/设计/注册/ edit.html.erb:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }, remote: true) do |f| %>
            <%= devise_error_messages! %>

            <% if @user.provider.blank? %>
              <div class="row row-condensed space-4">
                <label class="col-sm-3" for="user_first_name">
                  Current Password
                </label>
                <div class="col-sm-9 form-group">
                  <%= f.password_field :password, autocomplete: "off", class: "form-control" %>
                </div>
              </div>

              <div class="row row-condensed space-4">
                <label class="col-sm-3" for="user_first_name">
                  New Password
                </label>
                <div class="col-sm-9 form-group">
                  <%= f.password_field :password, autocomplete: "off", :class => "form-control", :required => true %>
                </div>
              </div>

              <div class="row row-condensed space-4">
                <label class="col-sm-3" for="user_first_name">
                  Re-type Password
                </label>
                <div class="col-sm-9 form-group">
                  <%= f.password_field :password_confirmation, autocomplete: "off", :class => "form-control", :required => true %>
                </div>
              </div>

              <div class="actions">
                <%= f.submit "Update", class: "btn btn-primary btn-md" %>
              </div>              

            <% end %>  

          <% end %>

控制器/ registrations_controller.rb

class RegistrationsController < Devise::RegistrationsController

  def create
    super
  end

  def update
    # For Rails 4
    account_update_params = devise_parameter_sanitizer.sanitize(:account_update)

    # required for settings form to submit when password is left blank
    if account_update_params[:password].blank?
      account_update_params.delete("password")
      account_update_params.delete("password_confirmation")
    end

    @user = User.find(current_user.id)
    if @user.update_attributes(account_update_params)
      set_flash_message :notice, :updated
      # Sign in the user bypassing validation in case their password changed
      sign_in @user, :bypass => true
      redirect_to edit_user_registration_path, notice: 'Your details was successfully updated.' 
    else
      render "edit"
    end
  end

end

所以我的问题是如何修改这些以便flash消息将通过AJAX显示如下图所示?

enter image description here

2 个答案:

答案 0 :(得分:2)

感谢Omkar,我设法解决了这个问题。我改变了一些东西,以使它完美地运作。以下是我更新的代码:

<强>控制器/ registrations_controller.rb:

  def update
    # For Rails 4
    account_update_params = devise_parameter_sanitizer.sanitize(:account_update)

    # required for settings form to submit when password is left blank
    if account_update_params[:password].blank?
      account_update_params.delete("password")
      account_update_params.delete("password_confirmation")
    end

    @user = User.find(current_user.id)

    @update = update_resource(@user, account_update_params)
    if @update 
      # Sign in the user bypassing validation in case their password changed
      sign_in @user, :bypass => true
    end

    respond_to do |format|
      format.html
      format.js
    end
  end

<强>视图/设计/注册/ update.js.erb:

<% if @update %>
  window.location.replace('<%= edit_user_registration_path %>');
<% else %>

  <% if @user.errors.messages.size > 0 %>
    <% @user.errors.each do |attr,err| %>
        $('#js-error-block').append('<%= attr %> <%= err %> <br/>');  
        $('.alert').show(); 
    <% end %>
  <% end %> 

<% end %>

<强>视图/设计/注册/ edit.html.erb:

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }, remote: true) do |f| %>         
  <div class="alert alert-danger" style="display:none;">
    <div id='js-error-block'></div>
  </div>          

  <div class="row row-condensed space-4">
    <label class="col-sm-3" for="user_first_name">
      Current Password
    </label>
    <div class="col-sm-9 form-group">
      <%= f.password_field :current_password, autocomplete: "off", class: "form-control", :required => true  %>
    </div>
  </div>

  <div class="row row-condensed space-4">
    <label class="col-sm-3" for="user_first_name">
      New Password
    </label>
    <div class="col-sm-9 form-group">
      <%= f.password_field :password, autocomplete: "off", :class => "form-control", :required => true %>
    </div>
  </div>

  <div class="row row-condensed space-4">
    <label class="col-sm-3" for="user_first_name">
      Re-type Password
    </label>
    <div class="col-sm-9 form-group">
      <%= f.password_field :password_confirmation, autocomplete: "off", :class => "form-control", :required => true %>
    </div>
  </div>

  <div class="actions">
    <%= f.submit "Update", class: "btn btn-primary btn-md" %>
  </div>              
<% end %>

<强>变化:

  1. 我没有直接使用update_attributes(account_update_params),而是使用update_resource(@user, account_update_params)并将其分配给@update变量。否则,错误与&#34;未知属性&#39; current_password&#39;&#34;将出来
  2. 我没有检查@ user.valid?,而是检查@update是否成功
  3. 我没有使用<%= devise_error_messages! %>,而是遍历@users错误,并相应地显示它。您可以在此处详细了解此信息:http://api.rubyonrails.org/v2.3/classes/ActiveRecord/Errors.html#M001905

答案 1 :(得分:1)

def update
  # For Rails 4
  account_update_params = devise_parameter_sanitizer.sanitize(:account_update)

  # required for settings form to submit when password is left blank
  if account_update_params[:password].blank?
    account_update_params.delete("password")
    account_update_params.delete("password_confirmation")
  end

  @user = User.find(current_user.id)
  if @user.update_attributes(account_update_params)
    # Sign in the user bypassing validation in case their password changed
    sign_in @user, :bypass => true
  end

  respond_to do |format|
    format.html
    format.js
  end

end

视图/设计/注册/更新的 JS .erb:

<% if @user.valid? %>
  # Redirect To path
  window.location.replace('<%= edit_user_registration_path %>');
<% else %>
  # Show Errors
  $('#js-error-block').html('<%= devise_error_messages! %>');
<% end %>

视图/设计/注册/ edit.html.erb:

在edit.html.erb中添加div以使用javascript更新DOM。

<div id='js-error-block'></div>

<强>流量:

  1. 用户提交表单(远程:true)
  2. 更新操作将被调用
  3. 因为请求是JS请求。 update.js.erb将在响应中呈现。
  4. update.js.erb将拥有更新DOM的代码或使用简单语言更新edit.html.erb页面。
  5. 有关详细信息,请参阅此rails cast:

    #136 jQuery & Ajax (revised)