我在使用Rails 4.2创建包含多个模型的表单时遇到了问题。 我正在创建一个表单,允许用户订购带有自定义条带支付表单的礼品卡。 我尝试了使用form_tag而不是simple_form_for和simple_fields_for的不同方法,我尝试了本网站提供的所有解决方案,但我无法找到解决这个问题的方法!
我的表格如下:
=simple_form_for @giftcard, url: gift_cards_path, html: {"accept-charset" => "UTF-8", :autocomplete => "off", :enctype => "multipart/form-data", :method => "post" } do |f|
(...)
= field_set_tag 'Delivery mode' do
.form-row
= f.label :delivery_mode, 'She receive the mail'
= f.radio_button :delivery_mode, 'email_to_recipient'
= f.label :delivery_mode, 'I receive the mail'
= f.radio_button :delivery_mode, 'email_to_giver'
= f.label :delivery_mode, 'Delivery with in box with a jewel'
= f.radio_button :delivery_mode, 'gift_box', id: 'gift_box'
= field_set_tag 'Who is the gift for ?' do
.form-row
= f.input :recipient_first_name, label: 'First Name'
.form-row
= f.input :recipient_last_name, label: 'Last Name'
.form-row
= f.input :recipient_email, placeholder: 'example@mail.com', label: 'Son adresse email'
.form-row
= f.input :message, placeholder: 'Your message', label: 'Son message'
= f.simple_fields_for :payment do |p|
.form-row
= p.input :card_number, label: 'Numéro de carte'
.form-row
= p.input :card_cvc, input_html: { "size" => 4, "data-stripe" => "cvv" }, label: 'CVV'
.form-row
= p.input :card_expiration_month, input_html: { "placeholder" => "MM", "size" => 2, "data-stripe" => "exp-month" }
= p.input :card_expiration_year, input_html: { "placeholder" => "YYYY", "size" => 4, "data-stripe" => "exp-year" }
.form-row
= f.button :submit, 'Send your gift !'
我的控制器如下:
def new
@giftcard = GiftCard.new
@payment = Payment.new
end
def create
@giftcard = GiftCard.new(giftcard_params)
@payment = Payment.new(creditcard_params)
@giftcard.amount += 9.90 if @giftcard.gift_box?
respond_to do |format|
if @giftcard.save && @payment.process_payment
code_coupon = CodeCoupon.create(name: giftcard.coupon, value: 0, category: 'membership', origin: 'gift')
if giftcard.delivery_mode == 'gift_box'
UserMailer.prepare_gift_box(@giftcard)
UserMailer.giftcard_recipe(@giftcard)
elsif @giftcard.delivery_mode == 'email_to_giver'
UserMailer.send_gift_card(@giftcard, @giftcard.giver_email)
UserMailer.giftcard_recipe(@giftcard)
elsif @giftcard.delivery_mode == 'email_to_recipient'
UserMailer.send_gift_card(@giftcard, @giftcard.recipient_email)
UserMailer.giftcard_recipe(@giftcard)
end
format.html { redirect_to @giftcard, notice: 'Votre carte cadeau à bien été créée et vous a été envoyé par email' }
format.json { render :show, status: :created, location: @giftcard }
else
format.html { render :new, locals: { errors: @giftcard.errors.full_messages } }
format.json { render json: @giftcard.errors, status: :unprocessable_entity }
end
end
end
private
def giftcard_params
params.require(:gift_card).permit(:recipient_email, :recipient_first_name, :recipient_last_name, :giver_email, :giver_phone, :giver_first_name, :giver_last_name, :message, :amount, :delivery_mode, :delivery_first_name, :delivery_last_name, :delivery_street, :delivery_city, :delivery_zip)
end
def creditcard_params
params.require(:payment).permit(:card_number, :card_cvc, :card_expiration_month, :card_expiration_year, :card_token )
end
陷入困境的模特:
class Payment
include ActiveModel::Model
attr_accessor :card_number, :card_cvc, :card_expiration_month, :card_expiration_year, :card_token
validates :card_number, presence: true
validates :card_cvc, presence: true
validates :card_expiration_month, presence: true
validates :card_expiration_year, presence: true
def payment_process
Stripe::Charge.create(
amount: amount * 100,
description: "paiement unique",
source: card_token,
currency: 'eur'
)
end
end
当我尝试验证表单时,它返回以下错误:
ActionController :: ParameterMissing - 缺少param或值为空:payment:
actionpack(4.2.8)lib / action_controller / metal / strong_parameters.rb:251:in require'
app/controllers/gift_cards_controller.rb:56:in
creditcard_params'
app / controllers / gift_cards_controller.rb:13:在'create'
如果我在creditcard_params方法中删除了require并点击了submit,我会进入日志: 未经许可的参数:付款 未允许的参数:utf8,authenticity_token,gift_card,commit (0.1ms)BEGIN (0.2ms)ROLLBACK
编辑
这是我在日志中收到的参数:
Started POST "/gift_cards" for ::1 at 2017-10-06 10:17:42 +0200
Processing by GiftCardsController#create as HTML
Parameters: {
"utf8"=>"✓",
"authenticity_token"=>"UB1keTN7YNDhaEBdIT6cYf/qrwr/QxCpFEYwvGDBLWmYvZiVjXxFg+bQ9vaPAfQTx32d/D7jHnShsTmsqMwLrA==",
"gift_card"=>{
"recipient_first_name"=>"",
"recipient_last_name"=>"",
"recipient_email"=>"",
"message"=>"",
"giver_first_name"=>"",
"giver_last_name"=>"",
"giver_email"=>"",
"giver_phone"=>"",
"delivery_first_name"=>"",
"delivery_last_name"=>"",
"delivery_street"=>"",
"delivery_city"=>"",
"delivery_zip"=>"",
"payment"=>{
"card_number"=>"",
"card_cvc"=>"",
"card_expiration_month"=>"",
"card_expiration_year"=>""
}
},
"commit"=>"Send your gift !"
}
提前感谢您的帮助,
此致
答案 0 :(得分:0)
在我看来,实现这一目标的一种方法是person_params
的变化如下
def person_params params.require(:gift_card).permit(:recipient_email, :recipient_first_name, :recipient_last_name, :giver_email, :giver_phone, :giver_first_name, :giver_last_name, :message, :amount, :delivery_mode, :delivery_first_name, :delivery_last_name, :delivery_street, :delivery_city, :delivery_zip, payment: [:card_number, :card_cvc, :card_expiration_month, :card_expiration_year]) end
这会将您在params中显示的所有参数列入白名单,
完成此操作后,您必须将create
操作更改为
@payment = Payment.new(person_params(params)[:payment])
而不是你的代码。
除此之外,根据您显示的模型@giftcard.save && @payment.payment_process
,如果条件发生了代码更改。
完整的解决方案如下:
def create
@giftcard = GiftCard.new(giftcard_params)
@payment = Payment.new(giftcard_params[:payment])
@giftcard.amount += 9.90 if @giftcard.gift_box?
respond_to do |format|
if @giftcard.save && @payment.payment_process
code_coupon = CodeCoupon.create(name: giftcard.coupon, value: 0, category: 'membership', origin: 'gift')
if giftcard.delivery_mode == 'gift_box'
UserMailer.prepare_gift_box(@giftcard)
UserMailer.giftcard_recipe(@giftcard)
elsif @giftcard.delivery_mode == 'email_to_giver'
UserMailer.send_gift_card(@giftcard, @giftcard.giver_email)
UserMailer.giftcard_recipe(@giftcard)
elsif @giftcard.delivery_mode == 'email_to_recipient'
UserMailer.send_gift_card(@giftcard, @giftcard.recipient_email)
UserMailer.giftcard_recipe(@giftcard)
end
format.html { redirect_to @giftcard, notice: 'Votre carte cadeau à bien été créée et vous a été envoyé par email' }
format.json { render :show, status: :created, location: @giftcard }
else
format.html { render :new, locals: { errors: @giftcard.errors.full_messages } }
format.json { render json: @giftcard.errors, status: :unprocessable_entity }
end
end
end
private
def giftcard_params
params.require(:gift_card).permit(:recipient_email, :recipient_first_name, :recipient_last_name, :giver_email, :giver_phone, :giver_first_name, :giver_last_name, :message, :amount, :delivery_mode, :delivery_first_name, :delivery_last_name, :delivery_street, :delivery_city, :delivery_zip, payment: [:card_number, :card_cvc, :card_expiration_month, :card_expiration_year])
end
end