问题描述
我终于找到了如何使用此实现条纹每月结算
目前,我的#new订阅表单和编辑表单的提交按钮创建并发送信用卡数据到Stripe。
但是由于某种原因,当我更新信用卡时,我一直收到此错误
无法将Symbol转换为String
app / controllers / subscriptions_controller.rb:38:在'update'中
$问题:这是由于coffeescript导致的错误,还是我的模型中的update_card方法导致此问题?
编辑表格
<%= form_for @subscription,:html => {:id => update_card} do | f | %>
<%= render'shared / error_messages',object:f.object%>
<%= f.hidden_field:plan_id%>
<%= f.hidden_field:user_id%>
<%= f.hidden_field:stripe_card_token%>
< h4>更改信用卡< / h4>
< div class =field>
<%= label_tag:card_number,信用卡号码%>
<%= text_field_tag:card_number,nil,name:nil%>
< / div>
< div class =field>
<%= label_tag:card_code,卡上的安全代码(CVV)%>
<%= text_field_tag:card_code,nil,name:nil%>
< / div>
< div class =field>
<%= label_tag:card_month,卡过期%>
<%= select_month nil,{add_month_numbers:true},{name:nil,id:card_month}%>
<%= select_year nil,{start_year:Date.today.year,end_year:Date.today.year + 15},{name:nil,id:card_year}%>
< / div>
<%= f.submit更改信用卡,:class => btn btn-primary%>
<%end%>
JS.COFFEE
jQuery - >
Stripe.setPublishableKey($('meta [name =stripe-key]')。attr('content'))
subscription.setupForm()
changecard.setupForm b
$ b ###这部分在咖啡脚本中工作得很好。
subscription =
setupForm: - >
$('#new_subscription')。submit - >
$('input [type = submit]')。attr('disabled',true)
如果$('#card_number')长度
subscription.processCard b false
else
true
processCard: - >
card =
{number:$('#card_number')。val(),
cvc:$('#card_code')。val(),
expMonth:$ ('#card_month')。val(),
expYear:$('#card_year')。val()}
Stripe.createToken(card,subscription.handleStripeResponse)
handleStripeResponse:(status,response) - >
if status == 200
$('#subscription_stripe_card_token')。val(response.id)
$('#new_subscription')[0] .submit()
else
$('#stripe_error')。text(response.error.message)
$('input [type = submit]')。attr('disabled',false)
###这是我的编辑表单的咖啡。
changecard =
setupForm: - >
$('#update_card')。submit - >
$('input [type = submit]')。attr('disabled',true)
如果$('#card_number')长度
changecard.processCard b false
else
true
processCard: - >
card =
{number:$('#card_number')。val(),
cvc:$('#card_code')。val(),
expMonth:$ ('#card_month')。val(),
expYear:$('#card_year')。val()}
Stripe.createToken(card,changecard.handleStripeResponse)
handleStripeResponse:(status,response) - >
if status == 200
$('#subscription_stripe_card_token')。val(response.id)
$('#update_card')[0] .submit()
else
$('#stripe_error')。text(response.error.message)
$('input [type = submit]')。attr('disabled',false)
MODEL
< ActiveRecord :: Base
attr_accessible:plan_id,:user_id,:email,:stripe_customer_token,:last_4_digits,
:card_token,:card_name,:exp_month,:exp_year::stripe_card_token
attr_accessor:stripe_card_token
def update_card(attrs)
customer = Stripe :: Customer.retrieve(stripe_customer_token)
customer.email [email protected]
customer.description =Subscription
###这用于信用卡数据
customer.card = attrs [:stripe_card_token]
customer.save
rescue Stripe :: StripeError => e
logger.errorStripe Error:+ e.message
errors.add:base,#{e.message}。
false
end
CONTROLLER
class SubscriptionsController< ApplicationController
def update
@subscription = current_user.subscription
###我使用方法update_card更新客户的卡
@ subscription.update_card (params [:subscription])
如果@ subscription.update_card
redirect_to edit_subscription_path,
flash [:success] ='信用卡已成功更新'
else
flash.alert ='无法更新卡。
render:edit
end
end
参考:
LOGS
在2014年为127.0.0.1启动PUT/ subscriptions / 5 -01-30 16:23:20 -0800
由SubscriptionsController处理#更新为HTML
参数:{utf8=>✓,authenticity_token=> ehyUD17CbH7MMOe98s + Kqkh + wGghntWkG4OpoqbnQaA =,
subscription=> {plan_id="1,user_id="1,
stripe_card_token=& tok_103PJj26f8kAprmwvAtoZFRq},id=>5}
用户加载(0.8ms)SELECTusers。* FROMusers
WHEREusers。remember_token ='xEeu1X6IK9gUAsna9b6Mow'
LIMIT 1
订阅加载(0.5ms)SELECTsubscriptions。*
FROMsubscriptionsWHEREsubscriptions。user_id= 1 LIMIT 1
重定向到
完成500内部服务器错误在1283ms
TypeError(无法将Symbol转换为字符串):
app / controllers / subscriptions_controller。 rb:38:in'update'
解决方案调用 update_card 以 params 作为参数:
@ subscription.update_card(params)
和 update_card 希望中的:stripe_card_token :
def update_card(params)
#...
customer.card = params [:stripe_card_token]
但是没有 params [:stripe_card_token] ,令牌在 params [:subscription] [:stripe_card_token] :
参数:{
...
subscription=> {...stripe_card_token=>tok_103PCo26f8kAprmwHCPjZ6T5},
}
params 结构也符合您的表单结构:
<%= form_for @subscription,:html => {:id => update_card} do | f | %>
...
<%= f.hidden_field:stripe_card_token%>
form_for @subscription 表单为 X 使用 subscription [X] ,以便 hidden_field 将在HTML中具有 name =subscription [stripe_card_token],并转换为 params [:subscription] [:stripe_card_token]
也许你的意思是:
@ subscription.update_card(params [:subscription])
@ subscription.update_card 没有任何参数。您的整个控制器方法应该看起来更像这样:
def update
@subscription = current_user.subscription
if @ subscription.update_card(params [:subscription])
redirect_to edit_subscription_path,:success => 更新卡。
else
flash.alert ='无法更新卡。
render:edit
end
end
I finally figured out how to implement Stripes Monthly Billing using this tutorial
Currently my Submit Button for both my #new_subscription form and edit form creates and sends credit card data to Stripe.
But for some reason I keep getting this error when I update the Credit Card
can't convert Symbol into String app/controllers/subscriptions_controller.rb:38:in `update'Question: Is this error due to the coffeescript, or is my update_card method in my model causing this problem?
EDIT FORM
<%= form_for @subscription, :html => { :id => "update_card" } do |f| %> <%= render 'shared/error_messages', object: f.object %> <%= f.hidden_field :plan_id %> <%= f.hidden_field :user_id %> <%= f.hidden_field :stripe_card_token %> <h4>Change Credit Card</h4> <div class="field"> <%= label_tag :card_number, "Credit Card Number" %> <%= text_field_tag :card_number, nil, name: nil %> </div> <div class="field"> <%= label_tag :card_code, "Security Code on Card (CVV)" %> <%= text_field_tag :card_code, nil, name: nil %> </div> <div class="field"> <%= label_tag :card_month, "Card Expiration" %> <%= select_month nil, {add_month_numbers: true}, {name: nil, id: "card_month"} %> <%= select_year nil, {start_year: Date.today.year, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %> </div> <%= f.submit "Change Credit Card", :class => "btn btn-primary" %> <% end %>JS.COFFEE
jQuery -> Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content')) subscription.setupForm() changecard.setupForm() ###That part is working great in the coffee script. subscription = setupForm: -> $('#new_subscription').submit -> $('input[type=submit]').attr('disabled', true) if $('#card_number').length subscription.processCard() false else true processCard: -> card = {number: $('#card_number').val(), cvc: $('#card_code').val(), expMonth: $('#card_month').val(), expYear: $('#card_year').val()} Stripe.createToken(card, subscription.handleStripeResponse) handleStripeResponse: (status, response) -> if status == 200 $('#subscription_stripe_card_token').val(response.id) $('#new_subscription')[0].submit() else $('#stripe_error').text(response.error.message) $('input[type=submit]').attr('disabled', false) ###This is the Coffee for my Edit Form.. changecard = setupForm: -> $('#update_card').submit -> $('input[type=submit]').attr('disabled', true) if $('#card_number').length changecard.processCard() false else true processCard: -> card = {number: $('#card_number').val(), cvc: $('#card_code').val(), expMonth: $('#card_month').val(), expYear: $('#card_year').val()} Stripe.createToken(card, changecard.handleStripeResponse) handleStripeResponse: (status, response) -> if status == 200 $('#subscription_stripe_card_token').val(response.id) $('#update_card')[0].submit() else $('#stripe_error').text(response.error.message) $('input[type=submit]').attr('disabled', false)MODEL
class Subscription < ActiveRecord::Base attr_accessible :plan_id, :user_id, :email, :stripe_customer_token, :last_4_digits, :card_token, :card_name, :exp_month, :exp_year, :stripe_card_token attr_accessor :stripe_card_token def update_card(attrs) customer = Stripe::Customer.retrieve(stripe_customer_token) customer.email = "[email protected]" customer.description = "Subscription" ###This is being used for the credit card data customer.card = attrs[:stripe_card_token] customer.save rescue Stripe::StripeError => e logger.error "Stripe Error: " + e.message errors.add :base, "#{e.message}." false endCONTROLLER
class SubscriptionsController < ApplicationController def update @subscription = current_user.subscription ### I use the method update_card to update the customer's card @subscription.update_card(params[:subscription]) if @subscription.update_card redirect_to edit_subscription_path, flash[:success] = 'Credit Card was Succesfully Updated.' else flash.alert = 'Unable to update card.' render :edit end endReference: Stripe Reference for Ruby
LOGS
Started PUT "/subscriptions/5" for 127.0.0.1 at 2014-01-30 16:23:20 -0800 Processing by SubscriptionsController#update as HTML Parameters: {"utf8"=>"✓", "authenticity_token"=>"ehyUD17CbH7MMOe98s+Kqkh+wGghntWkG4OpoqbnQaA=", "subscription"=>{"plan_id"=>"1", "user_id"=>"1", "stripe_card_token"=>"tok_103PJj26f8kAprmwvAtoZFRq"}, "id"=>"5"} User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."remember_token" = 'xEeu1X6IK9gUAsna9b6Mow' LIMIT 1 Subscription Load (0.5ms) SELECT "subscriptions".* FROM "subscriptions" WHERE "subscriptions"."user_id" = 1 LIMIT 1 Redirected to Completed 500 Internal Server Error in 1283ms TypeError (can't convert Symbol into String): app/controllers/subscriptions_controller.rb:38:in `update'解决方案You're calling update_card with params as the argument:
@subscription.update_card(params)and update_card is expecting :stripe_card_token in params:
def update_card(params) #... customer.card = params[:stripe_card_token]but there is no params[:stripe_card_token], the token is in params[:subscription][:stripe_card_token]:
Parameters: { ... "subscription"=>{ ... "stripe_card_token"=>"tok_103PCo26f8kAprmwHCPjZ6T5"}, }That params structure also matches your form's structure:
<%= form_for @subscription, :html => { :id => "update_card" } do |f| %> ... <%= f.hidden_field :stripe_card_token %>The form_for @subscription will set up the form to use subscription[X] for field X so that hidden_field will have name="subscription[stripe_card_token]" in the HTML and that translates to params[:subscription][:stripe_card_token] in the controller.
Perhaps you mean to say:
@subscription.update_card(params[:subscription])You also have a stray call to @subscription.update_card without any arguments. Your whole controller method should probably look more like this:
def update @subscription = current_user.subscription if @subscription.update_card(params[:subscription]) redirect_to edit_subscription_path, :success => 'Updated Card.' else flash.alert = 'Unable to update card.' render :edit end end
这篇关于更新条纹信用卡与咖啡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!