実現したいこと
ご覧頂きありがとうございます。
現在オリジナルアプリにてPayJPを用いたクレジットカード決済機能を実装しています。
ところが、クレジットカードに情報を記入し、登録しようとすると以下のエラーメッセージが表示されます。
ActiveRecord::NotNullViolation in CardsController#create Mysql2::Error: Field 'token_id' doesn't have a default value
クレジットカードのトークンIDに値が入力されていない旨の内容です。
以下に記述した範囲外で、確認したい箇所がございましたらどうぞ遠慮なくお申し付けください。
どうかお力添えをよろしくお願い申し上げます。
発生しているエラー
該当のソースコード
ruby
1#cards_controller 2 def create 3 Payjp.api_key = ENV["PAYJP_SECRET_KEY"] 4 customer = Payjp::Customer.create( 5 description: 'test', 6 card: params[:token_id] 7 ) 8 card = Card.new( 9 customer_id: customer.id, 10 token_id: params[:token_id], 11 user_id: current_user.id 12 ) 13 14 if card.save 15 redirect_to root_path 16 else 17 redirect_to new_card_path 18 end 19 end
ruby
1#マイグレーションファイル 2 3 def change 4 create_table :cards do |t| 5 t.string :customer_id, null: false 6 t.string :token_id, null: false 7 t.references :user, foreign_key: true 8 t.timestamps 9 end 10 end
Javascript
1//app/javascript/card.js 2const pay = () => { 3 Payjp.setPublicKey(process.env.PAYJP_PUBLIC_KEY); 4 5 const form = document.getElementById("card_form"); 6 form.addEventListener("submit", function(e) { 7 e.preventDefault(); 8 9 const formResult = document.getElementById("card-form"); 10 const formData = new FormData(formResult); 11 12 const card = { 13 number: formData.get("order[number]"), 14 cvc: formData.get("order[cvc]"), 15 exp_month: formData.get("order[exp_month]"), 16 exp_year: `20${formData.get("order[exp_year]")}`, 17 }; 18 19 Payjp.createToken(card, function(status, response) { 20 if (status === 200) { 21 const token = response.id; 22 const tokenObj = `<input value=${token} name='token_id' type="hidden">`; 23 const cardForm = document.getElementById("card_form"); 24 cardForm.insertAdjacentHTML("beforeend", tokenObj); 25 document.getElementById("number").removeAttribute("name"); 26 document.getElementById("name").removeAttribute("name"); 27 document.getElementById("cvc").removeAttribute("name"); 28 document.getElementById("exp_month").removeAttribute("name"); 29 document.getElementById("exp_year").removeAttribute("name"); 30 document.getElementById("card_form").submit(); 31 } else { 32 alert("カード情報が正しくありません") 33 } 34 }); 35 }); 36}; 37window.addEventListener("load", pay);
ruby
1# app/views/cards/new.html.erb 2 3 <%= form_with url: cards_path, id: 'card-form', class: 'card-form',local: true do |f| %> 4 <div class="Cardpage"> 5 <h1>カード登録</h1> 6 </div><br> 7 <div class="field"> 8 <%= f.label :number, "【カード番号】" %> 9 <%= f.text_field :number, class:"number", placeholder:"カード番号(半角英数字)", maxlength:"16" %> 10 </div> 11 12 <div class="field"> 13 <%= f.label :cvc ,"【CVC】" %> 14 <%= f.text_field :cvc, class:"cvc", placeholder:"カード背面にある3桁の番号", maxlength:"4" %> 15 </div> 16 <div class="field"> 17 <br> 18 <p>【有効期限】</p> 19 <div class='input-expiration-date-wrap'> 20 <%= f.select :exp_month, 1..12, {include_blank: "---"}, class: "exp_month" %> 21 <p>月</p> 22 <%= f.select :exp_year, 20..25, {include_blank: "---"}, class: "exp_year" %> 23 <p>年</p> 24 </div> 25 </div> 26 <%= f.submit "登録する" , class:"button" %> 27 <% end %> 28
ruby
1# app/views/layouts/application.html.erb 2 3#省略 4 <%= csrf_meta_tags %> 5 <%= csp_meta_tag %> 6 <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha256-UzFD2WYH2U1dQpKDjjZK72VtPeWP50NoJjd26rnAdUI=" crossorigin="anonymous" /> 7 <script type="text/javascript" src="https://js.pay.jp/v1/"></script> 8 <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> 9 <%= javascript_include_tag 'application'%> 10 11#省略
ruby
1# log 2app/controllers/cards_controller.rb:19:in `create' 3Started POST "/cards" for ::1 at 2021-06-19 18:52:26 +0900 4 [1m[35m (0.9ms)[0m [1m[35mSET NAMES utf8, @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'), @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483[0m 5Processing by CardsController#create as HTML 6 Parameters: {"authenticity_token"=>"e04vwuk1AcQ2o1/LQUS/oCS0ExTNj89/BHX61QAaFzfAGx1ULeOx7YZyuZbH+n5y30agZ7x3oJCHgU0IXoMOzA==", "number"=>"4242424242424242", "cvc"=>"123", "exp_month"=>"4", "exp_year"=>"24", "commit"=>"登録する"} 7 [1m[36mUser Load (0.7ms)[0m [1m[34mSELECT `users`.* FROM `users` WHERE `users`.`id` = 3 ORDER BY `users`.`id` ASC LIMIT 1[0m 8 ↳ app/controllers/cards_controller.rb:16:in `create' 9 [1m[35m (0.2ms)[0m [1m[35mBEGIN[0m 10 ↳ app/controllers/cards_controller.rb:19:in `create' 11 [1m[36mUser Load (0.3ms)[0m [1m[34mSELECT `users`.* FROM `users` WHERE `users`.`id` = 3 LIMIT 1[0m 12 ↳ app/controllers/cards_controller.rb:19:in `create' 13 [1m[36mCard Create (0.8ms)[0m [1m[32mINSERT INTO `cards` (`customer_id`, `user_id`, `created_at`, `updated_at`) VALUES ('cus_5ca969407619bdc0991f102e3e00', 3, '2021-06-19 09:52:33.617374', '2021-06-19 09:52:33.617374')[0m 14 ↳ app/controllers/cards_controller.rb:19:in `create' 15 [1m[35m (0.1ms)[0m [1m[31mROLLBACK[0m 16 ↳ app/controllers/cards_controller.rb:19:in `create' 17Completed 500 Internal Server Error in 7099ms (ActiveRecord: 2.1ms | Allocations: 409797) 18 19 20 21ActiveRecord::NotNullViolation (Mysql2::Error: Field 'token_id' doesn't have a default value): 22 23app/controllers/cards_controller.rb:19:in `create' 24
試したこと
createアクションにbinding,pryをかけ、デバックを行うが生成されたパラメーターにtoken_id自体確認できなかった。
マイグレーションファイルと実際のcard.jsのカラム名を照らし合わせるが、記述ミスは見受けられず。
フォームに入力したクレジットカード情報はパラメーターにあるので、カード情報は取得できている様子。
参考
【Rails】 PAYJPを使ってクレジットカード決済を導入しよう!
【Rails】PAYJPでトークン生成時のエラー解決
Mysql2::Error: Field '****' doesn't have a default valueに二回もハマった話
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。