2017-10-05 228 views
0

我在使用Rails 4.2创建具有多个模型的表单时遇到问题。 我正在创建一个表单,允许用户使用自定义条形付款方式一次性订购礼品卡。 我尝试了不同的方式使用form_tag而不是simple_form_for和simple_fields_for,我尝试了所有在这个网站上提供的解决方案,但我找不到一个出路!Rails 4.2:使用多个模型的表单 - 缺少param或值

我的格式如下:

 =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: '[email protected]', 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 is missi纳克或值是空的:付款: ActionPack的(4.2.8)LIB/action_controller /金属/ strong_parameters.rb:251:在require' app/controllers/gift_cards_controller.rb:56:in creditcard_params' 应用程序/控制器/ gift_cards_controller.rb:13:在`创建”

如果我删除的creditcard_params方法的需要,我点击提交,我在日志中得到: 不允许的参数:支付 不允许的参数:UTF8,authenticity_token,GIFT_CARD,提交 (0.1毫秒)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

嗨@VaibhavDhoke谢谢你的回答,我把参数放在编辑部分! –

回答

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在if条件中有代码更改。

完整的解决方案将是如下:

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 
+0

谢谢你的回答Vaibhav,我的Giftcard模型和控制器其实还有其他一些麻烦。所以我必须先解决它们,然后我会直接给你提供解决方案的反馈:-) –