2014-11-25 79 views
2

我無法弄清楚當我嘗試使用AJAX加載ActiveRecord驗證錯誤時,我所做的不正確。我不能得到ajax:錯誤觸發,除非我已經提交了一個有效的表單,並觸發ajax:成功。我試圖只綁定ajax:錯誤,看看成功是否會阻止它。我已閱讀了關於working with javascript in rails的rails文檔,並且Google無法使用我的問題。我試圖使用.bind()和.on(),但我沒有看到有什麼區別。我確信我有一些令人難以置信的簡單,我錯過了,但我一直在看這太久,我似乎沒有得到任何地方。Rails 4 ajax:錯誤不會觸發,除非ajax:成功先被觸發

這是代碼。

模型

class User < ActiveRecord::Base 
    before_create :set_activation_key 
    before_save :encrypt_password 
    before_save :downcase_username 
    after_save :clear_password 

    validates :username, 
      format: { 
       with: /\A.*\z/, 
       message: 'invalid' 
      }, 
      uniqueness: {message: 'already in use'}, 
      presence: {message: 'cannot be blank'} 

    validates :email_address, 
      format: { 
       with: /\[email protected]+\..+\z/, 
       message: 'invalid' 
      }, 
      uniqueness: {message: 'already in use'}, 
      presence: {message: 'cannot be blank'} 


    validates :password, :confirmation => true, 
      presence: {message: 'cannot be blank'}, 
      length: {:within => 6..20, 
        :too_long => 'too long', 
        :too_short => 'too short', 
      } 

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

    def clear_password 
    self.password = nil 
    end 

    def set_activation_key 
    self.activation_key = SecureRandom.urlsafe_base64 
    end 

    def downcase_username 
    self.username = self.username.downcase 
    end 

    def self.authenticate(username, password) 
    user = User.find_by_username(username.to_s.downcase) 
    if user && user.password == BCrypt::Engine.hash_secret(password, user.salt) 
     user 
    else 
     nil 
    end 
    end 
end 

控制器

class Users::UsersController < ApplicationController 

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

    # POST /users 
    def create 
    @user = User.new(user_params) 

    respond_to do |format| 
     if @user.save 
     UserMailer.registration_email(@user.email_address).deliver 
     format.html { redirect_to root_path, notice: 'Check your email' } 
     format.js 
     else 
     format.html { render action: 'new' } 
     format.js { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    private 

    def user_params 
    params.require(:user).permit(:username, :email_address, :password, :password_confirmation) 
    end 
end 

<%= form_for User.new, remote: true do |f| %> 
    <div id="registration_messages"></div> 
    <div id="registration_errors"></div> 
    <%= f.label :username %> 
    <%= f.text_field :username%> 

    <%= f.label :email_address %> 
    <%= f.text_field :email_address %> 

    <%= f.label :password %> 
    <%= f.password_field :password %> 

    <%= f.label :password_confirmation, 'Confirm Password' %> 
    <%= f.password_field :password_confirmation %> 

    <%= f.submit 'Register', :class => 'tiny button' %> 
    <a class="close-reveal-modal">&#215;</a> 
<% end %> 

create.js.erb

$(document).ready(function() { 
    $('#new_user') 
      .bind("ajax:success", function(event, data, xhr, status){ 
       var $form = $(this); 
       $form.find('input[type=text], input[type=password], textarea').val(''); 
       $("div#registration_messages").append('<div data-alert class="alert-box success">Check your email</div>'); 
      }).bind("ajax:error", function(event, data, xhr, error){ 
       console.log(event); 
       console.log(data); 
       console.log(xhr); 
       console.log(error); 
       alert("ajax:error"); 
      }); 
}); 
+0

我不是太熟悉這個品牌的Rails/AJAX的,但我不知道叫 '渲染' 在你的respond_to塊的其他人阻止它加載部分。嘗試刪除'render json:@ user.errors,'並查看它是否有效。 – steel 2014-11-25 15:17:29

+0

我懷疑同樣的事情,但我還沒有找到使其工作的方法。我無法徹底刪除渲染。我試圖刪除它,我得到了其他錯誤。我目前不在我的開發機器上,所以我不記得昨晚發生了什麼。我知道簡單地刪除它並不能產生預期的結果。我將閱讀[this](http://guides.rubyonrails.org/layouts_and_rendering.html#using-render),看看我是否能從中找到解決方案。 – EDuncan 2014-11-25 17:53:07

回答

4

這不會幫助你當前的技術,但你可以嘗試在純JQuery的做這件事和溝js.erb文件。一旦你掌握了它,我總是發現這種方式更直接。我期望像下面的代碼不會產生你所看到的問題。

控制器

# POST /users 
def create 
    @user = User.new(user_params) 

    respond_to do |format| 
    if @user.save 
     UserMailer.registration_email(@user.email_address).deliver 
     format.html { redirect_to root_path, notice: 'Check your email' } 
     format.js { render nothing: true, status: :created } 
    else 
     format.html { render action: 'new' } 
     format.js { render json: @user.errors, status: :unprocessable_entity } 
    end 
    end 
end 

javascript.js

# could go in application.js while you're testing it, but best to factor it out into it's own file. 
    $('form#new_user').on('ajax:success', function(event, data, xhr, status) { 
    var $form = $(this); 
    $form.find('input[type=text], input[type=password], textarea').val(''); 
    $("div#registration_messages").append('<div data-alert class="alert-box success">Check your email</div>'); 
    }); 
    $('form#new_user').on('ajax:error', function(event, data, xhr, status) { 
    console.log(event); 
    console.log(data); 
    console.log(xhr); 
    console.log(error); 
    alert("ajax:error"); 
    }); 
+0

'其他方式是什麼?'你把這個放在application.js文件中嗎? – EDuncan 2014-11-26 00:52:16

+0

我不會把它放在application.js中,但是在其他一些javascript文件中。我發現這種方式比Rails方式更普遍。 – steel 2014-11-26 01:08:34

+0

@EDuncan,我已經使用了這段代碼。 – steel 2014-11-26 01:32:01