Ruby on rails 条纹&x2B;设计在注册用户时在模式对话框中显示所有可能的条带错误(和设计错误)

Ruby on rails 条纹&x2B;设计在注册用户时在模式对话框中显示所有可能的条带错误(和设计错误),ruby-on-rails,devise,stripe-payments,Ruby On Rails,Devise,Stripe Payments,问题是我不能在注册模式对话框上显示条带错误 Javascript: $.externalScript('https://js.stripe.com/v1/').done(function(script, textStatus) { Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content')); var subscription = { setupForm: function() { ret

问题是我不能在注册模式对话框上显示条带错误

Javascript:

$.externalScript('https://js.stripe.com/v1/').done(function(script, textStatus) {
  Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content'));
  var subscription = {
    setupForm: function() {
      return $('form').submit(function() {
        $('input[type=submit]').prop('disabled', true);
        if ($('#card_number').length) {
          subscription.processCard();
          return false;
        } else {
          return true;
        }
      });
    },
    processCard: function() {
      var card;
      card = {
        name: $('#user_name').val(),
        number: $('#card_number').val(),
        cvc: $('#card_code').val(),
        expMonth: $('#card_month').val(),
        expYear: $('#card_year').val()
      };
      return Stripe.createToken(card, subscription.handleStripeResponse);
    },
    handleStripeResponse: function(status, response) {
      if (status === 200) {
        $('#stripe_token').val(response.id)
        $('form')[0].submit()
      } else {
        $('#stripe_error').text(response.error.message).show();
        return $('input[type=submit]').prop('disabled', false);
      }
    }
  };
  return subscription.setupForm();
}))

在同一个js文件中,我对Desive的create方法进行了ajax调用,但我始终得到null值作为错误。所以我猜下面的部分和上面的部分不能同时进行。我试图合并它们,并在上面的HandleStripereResponse函数中进行ajax调用,但随后出现了一些其他问题

$('.signup').click(function(e){
e.preventDefault();
$.ajax ({
  url: '/users',
  method: 'POST',
  dataType: "JSON",
  success: function(data) {
    if (data.status == 'failed') {
      $('#stripe_error').show().text(data.error_message);
      return false;
    }
  }
});
}))

设计注册控制器:

def create
build_resource
user = User.new params[:user]

if user.save_with_payment 
  if user.active_for_authentication?
    set_flash_message :notice, :signed_up if is_navigational_format?
    sign_in(resource_name, user)
    # respond_with resource, :location => after_sign_up_path_for(user)
    render json: { status: 'success', resource: user }
  else
    set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
    expire_session_data_after_sign_in!
    respond_with user, :location => after_inactive_sign_up_path_for(user)
  end
else
  clean_up_passwords user
    render json: { status: 'failed', error_message: user.save_with_payment }
end
结束

用户模型:

def save_with_payment
  if valid?
    stripe_customer = Stripe::Customer.create(
      :email => email,
      :source  => stripe_token
    )
    self.customer_id = stripe_customer.id
    update_stripe_user_details
    save!
  end

  rescue Stripe::InvalidRequestError => e
    logger.error "Stripe error while creating customer: #{e.message}"
    errors.add :base, "There was a problem with your credit card."
  rescue Stripe::CardError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::InvalidRequestError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::AuthenticationError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::APIConnectionError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue Stripe::StripeError => e
    stripe_error e, e.message
    errors.add :base, e.message
  rescue => e
    stripe_error e, e.message
    errors.add :base, e.message
end 

请给我指出正确的方向,我正在失去想法。

你的主要问题是,你试图在一个控制器的动作中做很多事情

您的注册控制器不仅负责处理用户表单输入,还负责处理第三方-如果您开始考虑这里潜在的代码路径数量,您会意识到这是一个疯狂的责任量

您可能要做的是将操作拆分:

POST /registrations # create a user profile
POST /registrations/:registration_id/payments # pay
这为您提供了一套明确的责任,并使用户可以更轻松地重试失败的付款,而无需从头开始,也无需设置过于复杂的来回传递参数的设置

如果您正在构建的是一个仅成员类型的站点,您希望限制付费用户的访问权限,那么您应该在授权层(而不是身份验证层)处理此问题

这在实践中意味着,您允许任何已完成注册的用户进行授权,但在检查用户是否有权查看任何内容时,请检查记录上的标志或计算记录上的付款数量

class Ability
  include CanCan::Ability
  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.payed_in_full?
      can :read, :all
    end
  end
end
编辑 问题是,在同一张有一个按钮的表单上,我需要注册>用户并输入条带卡详细信息

是的,这正是重点。你需要改变你的方法

如果可以接受ajax解决方案,您可以执行以下操作:

function sendForm($form){
  return $.ajax($form.attr('action'), {
    data: $form.serializeArray(),
    method: 'POST',
    dataType: "JSON",
  });
}

$(document).on('.signup', 'submit', function(){
  var $form = $(this);
  var promise = sendForm($form);
  promise.done(function(data, textStatus, jqXHR ){
    if (jqXHR.statusText === "OK") {
       console.log("User signup was successful");
       $form.toggleClass('signup payup');
       $form.attr('action', '/payments');
       $form.submit(); // this will cause the '.payup', 'submit' event
    else {
       console.log("User signup failed");
       // todo - display errors
    }
  });

  return false; // prevent default action
});

$(document).on('.payup', 'submit', function(){
  var $form = $(this);
  // should post to something like `/payments`
  var promise = sendForm($form);
  promise.done(function(data, textStatus, jqXHR ){
    if (jqXHR.statusText === "OK") {
       console.log("Payment was created successfully");
    else {
       console.log("Payment failed");
       // todo - display errors
    }
  });

  return false; // prevent default action
});

这将为您提供两个不同的HTTP调用,从API的角度来看,这要简单得多,而用户体验是他只提交表单一次。

此外,您可能需要考虑使用服务对象与条带API进行对话。向模型类中添加第三方API通常会使它们成为疯狂的神类,它们知道如何了解周围的应用程序。谢谢你的解释。问题是,在同一张有一个按钮的表单上,我需要注册用户并输入条带卡详细信息。所以我有一个按钮,需要注册用户,检查电子邮件等是否有效,并检查条带信息输入以及点击。即使我有两条路线,我也不确定如何将其与设计创建操作连接。请参阅我的编辑。如果您决定以自己的方式执行,那么实际上必须将一些表单数据与ajax调用一起发送给
/用户
。好的,太好了。我的控制器的创建方法是否保持不变,或者我需要更改它?清除所有与处理条带支付相关的垃圾。确保控制器返回有效输入的
200 OK
(或使用创建的
201
)和输入无效的
422不可访问实体。如果您只使用JSON进行响应,那么也可以删除flash消息。