2014-10-19 27 views
0

我正在尝试使用信用卡付款订阅Stripe。无法获得自定义Stripe表单以使用Ruby on Rails

我目前正在获取ForbiddenAttributesError,日志如下。

ActiveModel::ForbiddenAttributesError 

Extracted source (around line #10): 

    def create 
    @subscription = Subscription.new(params[:subscription]) 
    if @subscription.save_with_payment 
     redirect_to @subscription, :notice => "Thank you for subscribing!" 
    else 

日志:

Processing by SubscriptionsController#create as HTML                                           
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"N58ei1EzQ+K4ATyJfSVOFIcZL96vML/wL3AWRuGAgH0=", "subscription"=>{"stripe_card_token"=>"tok_14pO112LeYog8mPkCsNDhIbK"}}              
    User Load (0.5ms) SELECT "users".* FROM "users" WHERE "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1                             
Completed 500 Internal Server Error in 4ms                                              

ActiveModel::ForbiddenAttributesError (ActiveModel::ForbiddenAttributesError):                                     
    app/controllers/subscriptions_controller.rb:10:in `create'                                         


    Rendered /home/action/.gem/ruby/2.1.1/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_source.erb (1.2ms)                        
    Rendered /home/action/.gem/ruby/2.1.1/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (2.0ms)                       
    Rendered /home/action/.gem/ruby/2.1.1/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.6ms)                   
    Rendered /home/action/.gem/ruby/2.1.1/gems/actionpack-4.1.0/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb within rescues/layout (28.1ms)  

subscriptions_controller.rb

class SubscriptionsController < ApplicationController 

    before_filter :authenticate_user! 

    def new 
     @subscription = Subscription.new 
    end 

    def create 
    @subscription = Subscription.new(params[:subscription]) 
    if @subscription.save_with_payment 
     redirect_to @subscription, :notice => "Thank you for subscribing!" 
    else 
     render :new 
    end 
    end 

    def show 
    @subscription = Subscription.find(params[:id]) 
    end 


end 

subscription.rb

class Subscription < ActiveRecord::Base 
    belongs_to :user 

    attr_accessor :stripe_card_token 

    before_create :save_with_payment 

    def save_with_payment 
      customer = Stripe::Customer.create(
       :card => stripe_card_token, 
       :description => "name", 
       :plan => 121, 
       :email => "email") 

      self.stripe_customer_id = customer.id 
      self.plan = 121 
    end 

end 

subscriptions.js.coffee

# Place all the behaviors and hooks related to the matching controller here. 
# All this logic will automatically be available in application.js. 

jQuery -> 
    Stripe.setPublishableKey($('meta[name="stripe-key"]').attr('content')) 
    subscription.setupForm() 

subscription = 
    setupForm: -> 
    $('#new_subscription').submit (e) -> 
     $('input[type=submit]').attr('disabled', true) 
     subscription.processCard() 
     return false 

    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) 
     false 

new.html.erb

<div class='panel panel-default'> 

    <div class='panel-heading'> 
     <h2>Subscribe</h2> 
    </div> 

    <div class='panel-body'> 

    <%= form_for @subscription, :html => {:class => 'main-form'} do |f| %> 

     <%= f.hidden_field :stripe_card_token %> 

     <div id='stripe_error' class="alert alert-info" style='display:none'> 
     </div> 


     <span class="help-block">Nothing is billed to your card for 7 days. <b>Guaranteed. </b> 
      <br>If you choose to continue after 7 days, only then will you be billed.</span> 

       <div class='form-group'> 
       <%= label_tag :card_number, "Credit Card Number" %> 
        <%= text_field_tag :card_number, nil, name: nil, class: 'form-control input-box', :placeholder => 'Credit Card Number' %> 
       </div> 

     <div class='row'> 

      <div class="col-xs-6"> 
       <%= label_tag :card_code, "Security Code on Card (CVC)" %> 
       <%= text_field_tag :card_code, nil, name: nil, class: 'form-control input-box', :placeholder => 'Security Code on Card (CVC)' %> 
      </div> 

      <div class="col-xs-6"> 
       <%= 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+1, end_year: Date.today.year+15}, {name: nil, id: "card_year"} %> 
      </div> 

     </div> 



      <div> 
       <%= f.submit "Subscribe", class: 'btn standard-button' %> 
      </div> 


     <% end %> 
    </div> 

</div> 

回答

4

你正由强大的参数挫败。

你可以不再做...

@subscription = Subscription.new(params[:subscription]) 

做到这一点(现在)是典型的方式...

@subscription = Subscription.new(subscription_params) 

而且有一个方法像...

def subscription_params 
    # add all the fields you want to allow to be updated via your form... 
    # example below is just :name, :email but you get the idea. 
    params.require(:subscription).permit(:name, :email) 
end 

它在最新的Rails中被更改的原因是,“黑帽”人不能再破解一个Web表单来包含不应该包含的属性允许最终用户更改。

+1

繁荣,很容易,忘记了,感谢队友,绝对传奇 – bnussey 2014-10-19 19:08:51