我有一个Rails表单,其中包含一个生成Stripe付款表单的脚本。嵌套在表单中的是fields_for
标记。这是我的全部费用/ new.html.erb文件:
<div class="row">
<div class="col-md-2"></div>
<div class="col-md-8">
<h3>Confirm address and make payment</h3>
<br>
<%= form_tag charges_path do %>
<%= fields_for :charges do |f| %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name, size: 20, :value => current_user.first_name, :class => 'form-control' %>
</div>
<div class="field">
<%= f.label :last_name %>
<%= f.text_field :last_name, size: 20, :value => current_user.last_name, :class => 'form-control' %>
</div>
<div class="field">
<%= f.label :address %>
<%= f.text_area :address, size: 40, :value => current_user.address, :class => 'form-control' %>
</div>
<div class="field">
<%= f.label :city %>
<%= f.text_field :city, size: 20, :value => current_user.city, :class => 'form-control' %>
</div>
<div class="field">
<%= f.label :state %>
<%= f.text_field :state, size: 2, :value => current_user.state, :class => 'form-control' %>
</div>
<div class="field">
<%= f.label :email %>
<%= f.text_field :email, size: 40, :value => current_user.email, :class => 'form-control' %>
</div>
<%= f.hidden_field :total_price, :value => @cart.total_price %>
<% end %>
<br>
<article>
<% if flash[:error].present? %>
<div id="error_explanation">
<p><%= flash[:error] %></p>
</div>
<% end %>
<label class="amount">
<span>Amount: <%= number_to_currency(@cart.total_price * 7.35) %></span>
</label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A one-time payment"
data-amount="<%= @cart.total_price * 735 %>"
data-locale="auto"></script>
<% end %>
</div>
<div class="col-md-2"></div>
</div>
这是我的Charges Controller:
class ChargesController < ApplicationController
include CurrentCart
before_action :set_cart, only: [:new, :create]
#before_action :set_charge, only: [:create]
def new
#@charge = Charge.new
end
def create #METHOD IS CALLED AFTER PAYMENT IS MADE
# Amount in cents
@charge = Charge.new(charge_params)
@amount = (@cart.total_price * 735)
customer = Stripe::Customer.create(
:email => params[:stripeEmail],
:source => params[:stripeToken]
)
charge = Stripe::Charge.create(
:customer => customer.id,
:amount => @amount,
:description => 'Witch or Wizard',
:currency => 'usd'
)
Cart.destroy(session[:cart_id])
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to new_charge_path
end
private
# Use callbacks to share common setup or constraints between actions.
def set_charge
@charge = Charge.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def charge_params
params.permit(:first_name, :last_name, :address, :city, :state, :email, :total_price)
end
end
当我提交此表单时,我收到与我的set_charge方法有关的错误:
无法使用'id'=
找到费用
我在这里做错了什么? Stripe功能正常,但我也试图将表单中包含的客户信息保存到数据库中。
这是我提交表单时的日志:
Started POST "/charges" for 127.0.0.1 at 2017-07-16 20:45:24 -0400
Processing by ChargesController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"9Kj986IJXX+NQuJ3msJelyYSYQfmQa+i+kmqdseoidR11mmt2T6xZrXi/WtgjAb2u6zs4GRF9nIr6/ZW3U4F/g==", "charges"=>{"first_name"=>"Matt", "last_name"=>"Cole", "address"=>"1 South Main St", "city"=>"Marietta", "state"=>"GA", "email"=>"mattaecole@gmail.com", "total_price"=>"4"}, "stripeToken"=>"tok_1AgNMTJG64O6iQtfUhLFVKZF", "stripeTokenType"=>"card", "stripeEmail"=>"mattaecole@gmail.com"}
Cart Load (0.2ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ? [["id", 71], ["LIMIT", 1]]
LineItem Load (0.7ms) SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ? [["cart_id", 71]]
Product Load (0.1ms) SELECT "products".* FROM "products" WHERE "products"."id" = ? LIMIT ? [["id", 17], ["LIMIT", 1]]
CACHE (0.0ms) SELECT "carts".* FROM "carts" WHERE "carts"."id" = ? LIMIT ? [["id", 71], ["LIMIT", 1]]
(0.1ms) begin transaction
CACHE (0.0ms) SELECT "line_items".* FROM "line_items" WHERE "line_items"."cart_id" = ? [["cart_id", 71]]
SQL (0.3ms) DELETE FROM "line_items" WHERE "line_items"."id" = ? [["id", 135]]
SQL (0.1ms) DELETE FROM "carts" WHERE "carts"."id" = ? [["id", 71]]
(1.7ms) commit transaction
Rendering charges/create.html.erb within layouts/application
Rendered charges/create.html.erb within layouts/application (1.0ms)
User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."id" ASC LIMIT ? [["id", 7], ["LIMIT", 1]]
Completed 200 OK in 1529ms (Views: 61.8ms | ActiveRecord: 6.0ms)
答案 0 :(得分:0)
问题是提交表单后没有发送id
,因此错误。
但是,您根本不需要这种方法,因为您正在创建Charge
并且尚未创建其id
。接下来,您在@charge
操作的第一行替换set_charge
(在create
中设置),即:
@charge = Charge.new(charge_params)
要修复错误只需删除来自控制器的以下行,您应该没问题:
before_action :set_charge, only: [:create]
通常,您只希望在更新记录时使用此类回调(即查找现有记录),即仅使用edit
和update
操作。
因此,如果您计划将此类操作添加到控制器,请更改以上行(而不是删除它),仅针对edit
和update
操作执行:
before_action :set_charge, only: [:edit, :update]