読者コミュニティ|【実践 Ruby on Rails】Stripe を使って EC サイトを作ろう(Rails 7 対応)
本の感想や質問をお気軽にコメントしてください。
失礼致します。
本記事にてアプリを作成しているのですが分からないことがございます。
12の決済処理を実装仕様にて決済が完了してリダイレクトされた後にカート内が0にならず更新されないです。
こちらのコミュニティでcreate orderメソッドの中のshippingをshipping_detailsに変更して再度決済を
完了してもカートの中身はそのままです。😰
解決方法教えて頂けないでしょうか🙏
補足
rails cにてendpointも登録、返信されましたが個人的にはstripeからcreate orderの情報が送られてない関連
だと思うのですが初心者なものでよく分かりません(~_~;)
webhooks_controller.rb
class Customer::WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def create
payload = request.body.read
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
endpoint_secret = Rails.application.credentials.dig(:stripe, :endpoint_secret)
event = nil
begin
event = Stripe::Webhook.construct_event(
payload, sig_header, endpoint_secret
)
rescue JSON::ParserError => e
# Invalid payload
p e
status 400
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
p e
status 400
return
end
case event.type
when 'checkout.session.completed'
session = event.data.object # sessionの取得
customer = Customer.find(session.client_reference_id)
return unless customer # 顧客が存在するかどうか確認
# トランザクション処理開始
ApplicationRecord.transaction do
order = create_order(session) # sessionを元にordersテーブルにデータを挿入
session_with_expand = Stripe::Checkout::Session.retrieve({ id: session.id, expand: ['line_items'] })
session_with_expand.line_items.data.each do |line_item|
create_order_details(order, line_item) # 取り出したline_itemをorder_detailsテーブルに登録
end
end
# トランザクション処理終了
customer.cart_items.destroy_all # 顧客のカート内商品を全て削除
OrderMailer.complete(email: session.customer_details.email).deliver_later
redirect_to session.success_url
end
end
private
def create_order(session)
Order.create!({
customer_id: session.client_reference_id,
name: session.shipping.name,
postal_code: session.shipping.address.postal_code,
prefecture: session.shipping.address.state,
address1: session.shipping.address.line1,
address2: session.shipping.address.line2,
postage: session.shipping_options[0].shipping_amount,
billing_amount: session.amount_total,
status: 'confirm_payment'
})
end
def create_order_details(order, line_item)
product = Stripe::Product.retrieve(line_item.price.product)
purchased_product = Product.find(product.metadata.product_id)
raise ActiveRecord::RecordNotFound if purchased_product.nil?
order_detail = order.order_details.create!({
product_id: purchased_product.id,
price: line_item.price.unit_amount,
quantity: line_item.quantity
})
purchased_product.update!(stock: (purchased_product.stock - order_detail.quantity)) # 購入された商品の在庫数の更新
end
end
先月から取り組ませていただき、3週間程度かけて本日ハンズオンを終えました!
お手本通りにアプリを完成させることができました。素晴らしい記事をありがとうございます。
とても実践的な内容と感じました。Railsに加え、Stripeの利用方法の理解が深まりました。
何かお役にたちたく、以下に誤記と思われた箇所を記載いたします。
・chapter 09: 厚固め→扱うため と思われます
・chapter 12: 「それでは、app/controllers/customer/checkouts_controller.rb を開いて下記コードを記述してください。」⇦記事中頃のこちらの文言は消し忘れのように思われました。
・chapter 13: 記事中頃の"config.time_zone = 'Tokyo'"の記述を追加するところのコード部について、chapter05で追加した「8. config/application.rb の編集」分が反映されていない模様でした。
・chapter 17: 「app/controllers/customer/orders_controller.rb」→customers_controller.rb コード部のファイル名が異なっているようでした。
以上です、ありがとうございました!
こんにちは。
嬉しいお言葉ありがとうございます。お役に立てて何よりです。
何よりこんなにも長い書籍を最後まで読んでいただきありがとうございました!
誤植についてのご指摘もありがとうございます。こういったコメント非常に助かります 😭
先ほど全ての誤植を修正いたしました。
これからもみなさまのお役に立てるよう、精進したいと思います。
今後ともよろしくお願いします!
下記ルーティングの設定の箇所で詰まっています。回答いただけると助かります泣
実はYoutubeのRecipegramの動画でもDeviseでのルーティングがうまくいかず挫折し、こちらの教材を発見し再挑戦しましたが、また同じような状況になってしまいました。
ターミナルでルーティングの状況を見ると大丈夫そうなのですが、ブラウザでhttp://localhost:8000/を開いた際、下記のようなエラーが出てしまいます。。(routes.rbのファイルを元に戻せば、Railsのデフォルトの画面は表示されます)
Recipegramの際はrailsやRubyのバージョンが動画と違う最新のものを使ってしまっていたため、今回はできるだけバージョンを合わせて作成しましたが、またエラーになってしまいました。
Ruby 2.5.7
Rails 7.0.4
Homebrew 3.6.16
Xcode Version 14.2 (14C18)
rbenv 1.2.0
Docker version 20.10.21, build baeda1f
Docker Compose version v2.13.0
アドバイスいただけると非常に助かります。よろしくお願いします!
こんにちは。
丁寧にご質問して頂き誠にありがとうございます。
Youtube もご覧頂き嬉しいです 😊
ルーティングエラーが吐かれているとのこと承知しました。
大変お手数なのですが、現在実装されている
-
routes.rb
の記述 - ディレクトリ構成(ディレクトリの名前を確認させて頂きたいです)
-
controllers/admin/sessions_controller.rb
の記述
以上三点について教えていただくことは可能でしょうか。
何卒よろしくお願いします。
返信ありがとうございます😭ハンズオンでは最後まで出来ませんでしたが、動画の内容もすごく良かったです。
特に何も変更してないのですが今ブラウザを開いたら違うエラーになってました。。
そちらも添付しておきます。
・routes.rb の記述
Rails.application.routes.draw do
# devise_for :customers
# devise_for :admins
devise_for :admins, controllers: {
sessions: 'admin/sessions'
}
devise_for :customers, controllers: {
sessions: 'customer/sessions',
registrations: 'customer/registrations'
}
root to: 'pages#home'
get '/up/', to: 'up#index', as: :up
get '/up/databases', to: 'up#databases', as: :up_databases
# Sidekiq has a web dashboard which you can enable below. It's turned off by
# default because you very likely wouldn't want this to be available to
# everyone in production.
#
# Uncomment the 2 lines below to enable the dashboard WITHOUT authentication,
# but be careful because even anonymous web visitors will be able to see it!
# require "sidekiq/web"
# mount Sidekiq::Web => "/sidekiq"
#
# If you add Devise to this project and happen to have an admin? attribute
# on your user you can uncomment the 4 lines below to only allow access to
# the dashboard if you're an admin. Feel free to adjust things as needed.
# require "sidekiq/web"
# authenticate :user, lambda { |u| u.admin? } do
# mount Sidekiq::Web => "/sidekiq"
# end
# Learn more about this file at: https://guides.rubyonrails.org/routing.html
end
・ディレクトリ構成(かなり長くなってしまいましたがので一部削除したものをこちらには記載してます。空白の行のところは削除したものがあるところです。もちろん実際のファイルは削除してません)
.
├── .git
│ ├── hooks
│ │ ├── applypatch-msg.sample
│ │ ├── commit-msg.sample
│ │ ├── fsmonitor-watchman.sample
│ │ ├── post-update.sample
│ │ ├── pre-applypatch.sample
│ │ ├── pre-commit.sample
│ │ ├── pre-merge-commit.sample
│ │ ├── pre-push.sample
│ │ ├── pre-rebase.sample
│ │ ├── pre-receive.sample
│ │ ├── prepare-commit-msg.sample
│ │ ├── push-to-checkout.sample
│ │ └── update.sample
│ ├── info
│ │ └── exclude
│ ├── logs
│ │ ├── refs
│ │ │ ├── heads
│ │ │ │ └── main
│ │ │ └── remotes
│ │ │ └── origin
│ │ │ └── main
│ │ └── HEAD
│ ├── objects
│ │ ├── 00
│ │ ├── info
│ │ └── pack
│ ├── refs
│ │ ├── heads
│ │ │ └── main
│ │ ├── remotes
│ │ │ └── origin
│ │ │ └── main
│ │ └── tags
│ ├── COMMIT_EDITMSG
│ ├── config
│ ├── description
│ ├── HEAD
│ └── index
├── .github
│ ├── docs
│ │ └── screenshot.jpg
│ └── workflows
│ └── ci.yml
├── app
│ ├── assets
│ │ ├── builds
│ │ │ ├── .keep
│ │ │ ├── application.css
│ │ │ ├── application.js
│ │ │ └── application.js.map
│ │ ├── config
│ │ │ └── manifest.js
│ │ ├── images
│ │ │ ├── .keep
│ │ │ └── ruby-on-rails.png
│ │ └── stylesheets
│ │ └── application.tailwind.css
│ ├── channels
│ │ └── application_cable
│ │ ├── channel.rb
│ │ └── connection.rb
│ ├── controllers
│ │ ├── admin
│ │ │ ├── confirmations_controller.rb
│ │ │ ├── omniauth_callbacks_controller.rb
│ │ │ ├── passwords_controller.rb
│ │ │ ├── registrations_controller.rb
│ │ │ ├── sessions_controller.rb
│ │ │ └── unlocks_controller.rb
│ │ ├── concerns
│ │ │ └── .keep
│ │ ├── customer
│ │ │ ├── confirmations_controller.rb
│ │ │ ├── omniauth_callbacks_controller.rb
│ │ │ ├── passwords_controller.rb
│ │ │ ├── registrations_controller.rb
│ │ │ ├── sessions_controller.rb
│ │ │ └── unlocks_controller.rb
│ │ ├── application_controller.rb
│ │ ├── pages_controller.rb
│ │ └── up_controller.rb
│ ├── helpers
│ │ ├── application_helper.rb
│ │ └── pages_helper.rb
│ ├── javascript
│ │ ├── controllers
│ │ │ ├── .keep
│ │ │ ├── application.js
│ │ │ └── index.js
│ │ └── application.js
│ ├── jobs
│ │ └── application_job.rb
│ ├── mailers
│ │ └── application_mailer.rb
│ ├── models
│ │ ├── concerns
│ │ │ └── .keep
│ │ ├── admin.rb
│ │ ├── application_record.rb
│ │ └── customer.rb
│ ├── views
│ │ ├── admin
│ │ │ ├── confirmations
│ │ │ │ └── new.html.erb
│ │ │ ├── mailer
│ │ │ │ ├── confirmation_instructions.html.erb
│ │ │ │ ├── email_changed.html.erb
│ │ │ │ ├── password_change.html.erb
│ │ │ │ ├── reset_password_instructions.html.erb
│ │ │ │ └── unlock_instructions.html.erb
│ │ │ ├── passwords
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── new.html.erb
│ │ │ ├── registrations
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── new.html.erb
│ │ │ ├── sessions
│ │ │ │ └── new.html.erb
│ │ │ ├── shared
│ │ │ │ ├── _error_messages.html.erb
│ │ │ │ └── _links.html.erb
│ │ │ └── unlocks
│ │ │ └── new.html.erb
│ │ ├── customer
│ │ │ ├── confirmations
│ │ │ │ └── new.html.erb
│ │ │ ├── mailer
│ │ │ │ ├── confirmation_instructions.html.erb
│ │ │ │ ├── email_changed.html.erb
│ │ │ │ ├── password_change.html.erb
│ │ │ │ ├── reset_password_instructions.html.erb
│ │ │ │ └── unlock_instructions.html.erb
│ │ │ ├── passwords
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── new.html.erb
│ │ │ ├── registrations
│ │ │ │ ├── edit.html.erb
│ │ │ │ └── new.html.erb
│ │ │ ├── sessions
│ │ │ │ └── new.html.erb
│ │ │ ├── shared
│ │ │ │ ├── _error_messages.html.erb
│ │ │ │ └── _links.html.erb
│ │ │ └── unlocks
│ │ │ └── new.html.erb
│ │ ├── layouts
│ │ │ ├── application.html.erb
│ │ │ ├── mailer.html.erb
│ │ │ └── mailer.text.erb
│ │ ├── pages
│ │ │ └── home.html.erb
│ │ └── .DS_Store
│ └── .DS_Store
├── bin
│ ├── docker-entrypoint-web
│ ├── rails
│ ├── rake
│ ├── rename-project
│ ├── setup
│ └── yarn
├── cable
│ └── config.ru
├── config
│ ├── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers
│ │ ├── assets.rb
│ │ ├── content_security_policy.rb
│ │ ├── devise.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── inflections.rb
│ │ ├── permissions_policy.rb
│ │ ├── rack_mini_profiler.rb
│ │ ├── redis.rb
│ │ └── sidekiq.rb
│ ├── locales
│ │ ├── devise.en.yml
│ │ └── en.yml
│ ├── .DS_Store
│ ├── application.rb
│ ├── boot.rb
│ ├── cable.yml
│ ├── database.yml
│ ├── environment.rb
│ ├── puma.rb
│ ├── routes.rb
│ ├── sidekiq.yml
│ ├── spring.rb
│ └── storage.yml
├── db
│ ├── migrate
│ │ ├── 20230110185440_devise_create_admins.rb
│ │ └── 20230110185533_devise_create_customers.rb
│ ├── schema.rb
│ └── seeds.rb
├── lib
│ ├── assets
│ │ └── .keep
│ └── tasks
│ └── .keep
├── log
│ └── .keep
├── public
│ ├── 502.html
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── browserconfig.xml
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── maintenance.html
│ ├── mstile-150x150.png
│ ├── robots.txt
│ ├── safari-pinned-tab.svg
│ └── site.webmanifest
├── storage
│ └── .keep
├── test
│ ├── channels
│ │ └── application_cable
│ │ └── connection_test.rb
│ ├── controllers
│ │ ├── .keep
│ │ ├── pages_controller_test.rb
│ │ └── up_controller_test.rb
│ ├── fixtures
│ │ └── files
│ │ └── .keep
│ ├── helpers
│ │ └── .keep
│ ├── integration
│ │ └── .keep
│ ├── mailers
│ │ └── .keep
│ ├── models
│ │ └── .keep
│ ├── system
│ │ └── .keep
│ ├── application_system_test_case.rb
│ └── test_helper.rb
├── tmp
│ ├── cache
│ │ ├── assets
│ │ │ └── sprockets
│ │ │ └── v4.0.0
│ │ └── bootsnap
│ │ ├── compile-cache-iseq
│ │ └── load-path-cache
│ ├── miniprofiler
│ ├── pids
│ │ └── server.pid
│ ├── sockets
│ ├── .keep
│ ├── development_secret.txt
│ └── restart.txt
├── vendor
│ └── .keep
├── .dockerignore
├── .DS_Store
├── .env
├── .env.example
├── .gitignore
├── .rubocop.yml
├── .yarnrc
├── CHANGELOG.md
├── config.ru
├── docker-compose.yml
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── LICENSE
├── package.json
├── postcss.config.js
├── Rakefile
├── README.md
├── run
├── tailwind.config.js
└── yarn.lock
・controllers/admin/sessions_controller.rb の記述
# frozen_string_literal: true
class Admin::SessionsController < Devise::SessionsController
# before_action :configure_sign_in_params, only: [:create]
# GET /resource/sign_in
# def new
# super
# end
# POST /resource/sign_in
# def create
# super
# end
# DELETE /resource/sign_out
# def destroy
# super
# end
# protected
# If you have extra params to permit, append them to the sanitizer.
# def configure_sign_in_params
# devise_parameter_sanitizer.permit(:sign_in, keys: [:attribute])
# end
end
よろしくお願いします!
ありがとうございます!
コード・ディレクトリ構成は問題なさそうですね。
一つ確認させて頂きたいのですが、下記コマンドは実行されましたでしょうか。
$ rails g devise:install
はい!実行してますね。
ありがとうございます!
$ rails db:migrate
も実行されていますでしょうか。
schema.rb
も見せて頂けると助かります!
はい!出来ているかと。お手数おかけしてすみません😅
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_01_10_185533) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "admins", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_admins_on_email", unique: true
t.index ["reset_password_token"], name: "index_admins_on_reset_password_token", unique: true
end
create_table "customers", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.string "name", null: false
t.integer "status", default: 0, null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["email"], name: "index_customers_on_email", unique: true
t.index ["reset_password_token"], name: "index_customers_on_reset_password_token", unique: true
end
end
なるほど!ありがとうございます!
手順もあってそうですねー🤔
そうしましたら大変お手数なのですが、GitHub 上に開発途中のコードをプッシュして頂くことは可能でしょうか。
私の方で動作確認させて頂きたいです!
すみません。ありがとうございます😭
Deviseのルーティング問題で1週間くらいRailsの学習が進められておらず、とても助かります。
一応チャプター7の作業は終えている状態かと思います。
こちらに載せておきます。
Github
ありがとうございます!
早速動作確認してみますね!
今出先ですので回答は明日になってしまうと思いますが、お待ちいただけると幸いです。
ありがとうございます!お待ちしてます^^
お待たさせしました!
先ほどいただいた GitHub コードを clone してきて環境構築を行ったところ、新規登録画面・ログイン画面ともに表示されました。
実行したコマンドは下記の通りです。
$ git clone git@github.com:yurikondo/ecommerce.git
$ cd ecommerce
$ docker-compose build --no-cache
$ docker-compose run --rm web bash
下記は、コンテナの中で実行しています。
$ rails db:create
$ rails db:migrate
コンテナからログアウトして、下記コマンドを実行しています。
$ docker-compose up
大変お手数ですが、一度
- コンテナの削除
- ボリュームの削除
- イメージの削除
を行っていただいて、上記の通りコマンドを実行して頂いてもよろしいでしょうか。
何卒よろしくお願いいたします。
http://localhost:8000/customers/sign_in で表示される画面は現時点だと画像の通りで合ってますよね?
本当にありがとうございます😭
エラーの原因としてはこちらのコマンドを打つ際にキャッシュか何かが残ってたのが原因だったのでしょうか。。。?今後またDockerを使う際は「--no-cache」を基本つけたほうがいいでしょうか?
$ docker-compose build --no-cache
そちらの画面で合っております!
エラーの原因については特定できませんでした。すみません🙏
キャッシュが影響していた可能性はありますね。
下記コマンドについては、build を実行する際に参照ファイルを更新したにもかかわらず、反映されない場合によく使いますね。
$ docker-compose build --no-cache
キャッシュを無効にしたいと言う場面でのみ --no-cache
をつければいいと思います。
承知しました!ありがとうございます^^
一気にこちらの教材を進めております!
現在ここまできたのですが、Dockerコンテナ内で下記コマンドを実行し、Stripe CLIをインストするという流れであってますでしょうか?
ご質問頂きありがとうございます!
Stripe CLI は Docker コンテナ内ではなく、ローカル にインストールするようお願いします。
Stripe CLI のコマンドをローカルで叩くことになるので!
Mac でしたら下記コマンドになりますね。
$ brew install stripe/stripe-cli/stripe
現在Chapter 7「認証機能を実装しよう」のあたりを進めています。
以下のコマンドについて質問があります。
$ rails g devise:controllers admin
$ rails g devise:controllers customer
$ rails g devise:views admins
$ rails g devise:views customers
こちらを実行後、views フォルダ配下のadmins, customersをadmin, customerに変更し、単数形に揃えていますが、controllerを生成するコマンドを
$ rails g devise:controllers admins
$ rails g devise:controllers customers
として複数形に揃えることはできないのでしょうか?
こうすれば修正が必要なくなるのではないかと思ったのですが...
<追記>
Chapter7終了時点で http://localhost:8000/ にアクセスすると、上の質問者さんと同じように以下のようなエラーに遭遇しました。
後日コンテナを再起動すると直ったので、原因はわかりませんでしたがお知らせしておきます。
こんにちは。
本書籍をご覧いただきありがとうございます!
【views フォルダ配下の名前について】
今回単数系にしたのは、名前空間を使用する際に単数系にした方が better かなと考えたためです。Rails ガイドでのディレクトリ名も admin と単数系になっていました。
ですがおっしゃる通り、複数形のままにすれば修正が不要になりますので、どちらでもよろしいかと思います。ありがとうございます。
【Chapter 07 終了時点でのエラーについて】
エラーが発生するとのご指摘ありがとうございます。
コンテナの再起動が必要であるとの旨を追加しました。
こういったコメント非常に助かります 😭
他にご不明点などあればコメントして頂けると幸いです。
ご回答ありがとうございます!
こちらこそ、こういった質問できる環境があるととても嬉しいです!
この教材も完走できるようにがんばります💪
名前空間については単数形/複数形どちらでも機能的には問題ないのですね。
自分でも少し調べてみたんですが、deviseのGitHubを見るとやはりcontrollerの生成はscopeに合わせるようです。
exampleでも複数形のものがありました。
ありがとうございます!
なるほど、devise の README.md
によると scope に合わせているんですね。
だとすると、名前空間をわざわざ単数形に変更する必要はなかったかもしれないです...
勉強になりました。
ありがとうございました。
今後ともよろしくお願いします!
はじめまして!
こちらの記事を参考にwebアプリ開発の練習をしているのですが、「UIを作成しよう」の部分でつまづいてしまっています。
具体的には、(おそらく)記事の通りにerbファイルを書いているにもかかわらず、UIが下記のようにcssがうまく反映されません。
<div class='pt-32 pb-12 md:pt-40 md:pb-20'>
<div class='pb-12 text-center md:pb-16'>
<h1 class='leading-tighter mb-4 text-7xl font-extrabold tracking-tighter md:text-8xl'>
<span class="p-2 bg-gradient-to-right from-purple-600 to-blue-500 text-transparent bg-clip-text">
ECommerce
</span>
</h1>
<div class='mx-auto max-w-3xl'>
<p class='mb-8 text-xl'>You will find what you are looking for.</p>
<div class='flex justify-center mt-5'>
<div class='mt-3'>
<%= link_to root_path, class:'group inline-flex items-center justify-center overflow-hidden rounded-lg bg-gradient-to-br from-purple-600 to-blue-500 p-0.5 font-medium text-gray-900 hover:text-white focus:ring-4 focus:ring-blue-300 group-hover:from-purple-600 group-hover:to-blue-500' do %>
<span class='rounded-md bg-white px-5 py-2.5 transition-all duration-75 ease-in group-hover:bg-opacity-0'>
Find Products
</span>
<% end %>
</div>
</div>
</div>
</div>
</div>
トップページだけでなく、管理者や顧客の認証画面でも同様にcssが上手く適用されません。。。
何が原因でこうなってしまうのでしょうか?
お力添え頂けると非常にありがたいですm(__)m
こんにちは。
ご質問頂きありがとうございます!
もしかすると ecommerce_css コンテナによるビルドがうまく動作していないのかもしれません。
再度ビルドし直すことは可能でしょうか。具体的には、下記コマンドを実行して頂ければと思います。データベースに保存されているデータは消失しますので、ご注意ください。
- 一度コンテナを削除する。
$ docker-compose down
- ボリュームを削除する。
$ docker volume prune -f
- キャッシュを使わずにビルドする。
$ docker-compose build --no-cache
- コンテナの中に入り、データベースのセットアップを行う。
$ rails db:create
$ rails db:migrate
- コンテナを立ち上げる。
$ docker-compose up
上記で解決しない場合、再度ご質問頂けると幸いです。
何卒よろしくお願いします。
迅速かつ丁寧なご対応ありがとうございます!
アドバイスのとおりに作業してみたところ、無事に解決できました!ありがとうございます!
また、異なる質問重ねて申し訳ないのですが、サインアップ時に名前を入力したにもかかわらず、バリデーションに引っかかってしまいます。自力で解決を試みたのですが原因をはっきりと特定できず、行きづまっている状態です。
何か推測できるエラーの原因や解決策はありませんでしょうか?
いえいえ、解決できて何よりです!
【サインアップ時にバリデーションに引っかかってしまう件について】
フォームに名前を入力したにも関わらず、バリデーションに引っかかってしまう場合は、コントローラへデータを送信する際に、name パラメータが許可されていない可能性があります。
下記の節の パラメータを許可 が正しく行われているかどうか確認してみてください。
ちなみにパラメータが許可されていない場合、Unpermitted parameter
というログが表示されていると思います。
解決しない場合は、再度ご質問して頂けると幸いです。
何卒よろしくお願いします。
解決できました!
ご指摘のとおり、パラメータを許可できていなかったようです。
ありがとうございます!😊
解決してよかったです!
これからも全力でサポートさせて頂きますので、また何か疑問点などありましたらお気軽にコメントして頂けると幸いです。今後ともよろしくお願いします。
こんばんは😊
現在11章のビュー作成の部分まで進んでいるのですが、カートに商品を追加するボタンを押すと下のようなルーティングエラーが発生してしまいます。
商品は現在2つ登録していて、どちらの商品もカートに追加できない状態です。
知識不足でどうすればよいか分からず困っています。
何かアドバイス頂けないでしょうか
以下現在の自分のコードです
Rails.application.routes.draw do
devise_for :admins, controllers: {
sessions: 'admin/sessions'
}
devise_for :customers, controllers: {
sessions: 'customer/sessions',
registrations: 'customer/registrations'
}
root to: 'pages#home'
namespace :admin do
resources :products, only: %i[index show new create edit update]
end
scope module: :customer do
resources :products, only: %i[index show]
resources :cart_items, only: %i[index create destroy] do
member do
patch 'increase'
patch 'decrease'
end
end
end
get '/up/', to: 'up#index', as: :up
get '/up/databases', to: 'up#databases', as: :up_databases
get '/', to: 'pages#home'
# Sidekiq has a web dashboard which you can enable below. It's turned off by
# default because you very likely wouldn't want this to be available to
# everyone in production.
#
# Uncomment the 2 lines below to enable the dashboard WITHOUT authentication,
# but be careful because even anonymous web visitors will be able to see it!
# require "sidekiq/web"
# mount Sidekiq::Web => "/sidekiq"
#
# If you add Devise to this project and happen to have an admin? attribute
# on your user you can uncomment the 4 lines below to only allow access to
# the dashboard if you're an admin. Feel free to adjust things as needed.
# require "sidekiq/web"
# authenticate :user, lambda { |u| u.admin? } do
# mount Sidekiq::Web => "/sidekiq"
# end
# Learn more about this file at: https://guides.rubyonrails.org/routing.html
end
class Customer::CartItemsController < ApplicationController
before_action :authenticate_customer!
before_action :set_cart_item, only: %i[increase decrease destroy]
def index
@cart_items = current_customer.cart_items
end
def create
increase_or_create(params[:cart_item][:product_id])
redirect_to cart_items_path, notice: 'Successfully added product to your cart'
end
def increase
@cart_item.increment!(:quantity, 1)
redirect_to request.referer, notice: 'Successfully updated your cart'
end
def decrease
decrease_or_destroy(@cart_item)
redirect_to request.referer, notice: 'Successfully updated your cart'
end
def destroy
@cart_item.destroy
redirect_to request.referer, notice: 'Successfully deleted one cart item'
end
private
def set_cart_item
@cart_item = current_customer.cart_items.find(params[:id])
end
def increase_or_create(product_id)
cart_item = current_customer.cart_items.find_by(product_id:)
if cart_item
cart_item.increment!(:quantity, 1)
else
current_customer.cart_items.build(product_id:).save
end
end
def decrease_or_destroy(cart_item)
if cart_item.quantity > 1
cart_item.decrement!(:quantity, 1)
else
cart_item.destroy
end
end
end
こんばんは。
ご質問頂きありがとうございます!
Routing Error ですので、存在しないルーティングにアクセスしてしまっているのがエラーの原因ですね。商品をカートに追加するボタンのパスを今一度ご確認ください。
下記のようなコードが記載されているでしょうか?
<%= form_with model: @cart_item, data: { turbo: false } do |f| %>
<%= f.hidden_field :product_id, :value => @product.id %>
<%= f.submit "Add to Cart", class:"w-full cursor-pointer focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2" %>
<% end %>
app/views/customer/products/show.html.erb
のコードも見せていただけると幸いです。
何卒よろしくお願いします。
ご指摘のコードは以下のようになっています。
よろしくお願いします🙇♂️
<div class="relative mx-auto max-w-screen-xl p-6">
<div class="grid grid-cols-1 items-start gap-9 md:grid-cols-2">
<div>
<%= image_tag @product.image, class: "aspect-square w-full rounded-xl object-cover" %>
</div>
<div class="sticky top-0">
<div class="flex flex-col justify-between">
<div class="flex justify-between mb-6">
<div class="max-w-[35ch]">
<h1 class="text-2xl font-bold">
<%= @product.name %>
</h1>
</div>
<p class="text-2xl font-bold"><%= number_to_currency(@product.price, unit: "¥", strip_insignificant_zeros: true) %></p>
</div>
<div class="mb-3">
<p>
<%= @product.description %>
</p>
</div>
<div class="mb-8">
<% if @product.stock > 0 %>
<span class="bg-blue-100 text-blue-800 text-xs font-semibold p-2 rounded">In stock (<%= @product.stock %>)</span>
<% else %>
<span class="bg-red-100 text-red-800 text-xs font-semibold p-2 rounded">Out of stock</span>
<% end %>
</div>
<% if @product.stock > 0 %>
<%= form_with model: @cart_item, data: { turbo: false } do |f| %>
<%= f.hidden_field :product_id, :value => @product.id %>
<%= f.submit "Add to Cart", class:"w-full cursor-pointer focus:outline-none text-white bg-green-700 hover:bg-green-800 focus:ring-4 focus:ring-green-300 font-medium rounded-lg text-sm px-5 py-2.5 mr-2 mb-2" %>
<% end %>
<% end %>
</div>
</div>
</div>
</div>
ご返信頂きありがとうございます。
ビューの記述は合ってるようです。
app/controllers/customer/products_controller.rb
に下記の記述はありますでしょうか。
def show
@product = Product.find(params[:id])
@cart_item = CartItem.new
end
夜分遅くにお返事いただきありがとうございます。
確認してみたところ、@cart_item とすべきところを @cart_items としてしまっていました。
修正後、正しく動作しました!
ありがとうございます😊
解決してよかったです!
また何か疑問点などありましたらお気軽にコメントして頂けると幸いです。
今後ともよろしくお願いします!
質問すみません!
11章のカート追加の部分で「ログから INSERT INTO "cart_items" という SQL 文が発行されていることを確認する」とありますが、どのようにすればログを確認できますか。
解決できました!🙇♂️
ご返信が遅れて申し訳ありません。
ログというのは、ターミナルのコンテナログのことですね。
解決したようでよかったです!
12章の決済処理の部分まできました!
自己解決したのですが、最後の動作確認の部分でエラーになってしまったのでお知らせです。
2023-02-16 21:04:06 --> payment_intent.created [evt_3Mc6C0GMeb4ApE5J0HlWnG5W]
2023-02-16 21:04:06 --> payment_intent.succeeded [evt_3Mc6C0GMeb4ApE5J0m8H0cQz]
2023-02-16 21:04:06 --> charge.succeeded [evt_3Mc6C0GMeb4ApE5J07UKoAjU]
2023-02-16 21:04:06 --> checkout.session.completed [evt_1Mc6C2GMeb4ApE5JoSP5fdG1]
2023-02-16 21:04:07 <-- [500] POST http://localhost:8000/webhooks [evt_1Mc6C2GMeb4ApE5JoSP5fdG1]
2023-02-16 21:04:07 <-- [204] POST http://localhost:8000/webhooks [evt_3Mc6C0GMeb4ApE5J07UKoAjU]
2023-02-16 21:04:07 <-- [204] POST http://localhost:8000/webhooks [evt_3Mc6C0GMeb4ApE5J0m8H0cQz]
2023-02-16 21:04:07 <-- [204] POST http://localhost:8000/webhooks [evt_3Mc6C0GMeb4ApE5J0HlWnG5W]
checkout.session.completed
のイベントでエラーになっています。
ログではshippingメソッドが無いと言われていました。
NoMethodError (undefined method `shipping' for #<Stripe::Checkout::Session:0x7a80 id=xxx>
Stripeのドキュメントを見てもshippingというキーは無さそうです。webhooks_controller.rb
のcreate_order
メソッドの中で、shipping
の部分をshipping_details
とすることで解決しました。
こんにちは。
引き続き本書籍をご覧いただきありがとうございます!
shipping メソッドが存在しない件について、ご指摘いただきありがとうございます。
先ほど、完成版のソースコードをクローンしてきて、決済処理を行ったところ正常に注文が完了してしまいました。session オブジェクトの中身をログに吐き出してみたのですが、なぜか shipping
というキーが存在していました。原因は不明です...
web_1 | Customer Load (1.0ms) SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT $2 [["id", 2], ["LIMIT", 1]]
web_1 | ↳ app/controllers/customer/webhooks_controller.rb:29:in `create'
web_1 | {
web_1 | "id": "cs_test_b1t9BcngGc2sbb3UoJ3xQ6MPVPthyRYQC7XKhGCJDuOtK2ldFKRBT47NmA",
web_1 | "object": "checkout.session",
web_1 | "after_expiration": null,
web_1 | "allow_promotion_codes": null,
web_1 | "amount_subtotal": 14760,
web_1 | "amount_total": 15260,
web_1 | "automatic_tax": {
web_1 | "enabled": false,
web_1 | "status": null
web_1 | },
web_1 | "billing_address_collection": null,
web_1 | "cancel_url": "http://localhost:8000/cart_items",
web_1 | "client_reference_id": "2",
web_1 | "consent": null,
web_1 | "consent_collection": null,
web_1 | "created": 1676811086,
web_1 | "currency": "jpy",
web_1 | "custom_fields": [
web_1 |
web_1 | ],
web_1 | "custom_text": {
web_1 | "shipping_address": null,
web_1 | "submit": null
web_1 | },
web_1 | "customer": null,
web_1 | "customer_creation": "if_required",
web_1 | "customer_details": {
web_1 | "address": {
web_1 | "city": null,
web_1 | "country": "JP",
web_1 | "line1": "檜原村",
web_1 | "line2": null,
web_1 | "postal_code": "190-0200",
web_1 | "state": "東京都"
web_1 | },
web_1 | "email": "yamada.taro@gmail.com",
web_1 | "name": "yamada taro",
web_1 | "phone": null,
web_1 | "tax_exempt": "none",
web_1 | "tax_ids": [
web_1 |
web_1 | ]
web_1 | },
web_1 | "customer_email": "yamada.taro@gmail.com",
web_1 | "expires_at": 1676897486,
web_1 | "invoice": null,
web_1 | "invoice_creation": {
web_1 | "enabled": false,
web_1 | "invoice_data": {
web_1 | "account_tax_ids": null,
web_1 | "custom_fields": null,
web_1 | "description": null,
web_1 | "footer": null,
web_1 | "metadata": {
web_1 | },
web_1 | "rendering_options": null
web_1 | }
web_1 | },
web_1 | "livemode": false,
web_1 | "locale": null,
web_1 | "metadata": {
web_1 | },
web_1 | "mode": "payment",
web_1 | "payment_intent": "pi_3MdCMtF4dCXP6zuk1hWWC4Tq",
web_1 | "payment_link": null,
web_1 | "payment_method_collection": "always",
web_1 | "payment_method_options": {
web_1 | },
web_1 | "payment_method_types": [
web_1 | "card"
web_1 | ],
web_1 | "payment_status": "paid",
web_1 | "phone_number_collection": {
web_1 | "enabled": false
web_1 | },
web_1 | "recovered_from": null,
web_1 | "setup_intent": null,
web_1 | "shipping": {
web_1 | "address": {
web_1 | "city": "",
web_1 | "country": "JP",
web_1 | "line1": "檜原村",
web_1 | "line2": null,
web_1 | "postal_code": "190-0200",
web_1 | "state": "東京都"
web_1 | },
web_1 | "name": "yamada taro"
web_1 | },
web_1 | "shipping_address_collection": {
web_1 | "allowed_countries": [
web_1 | "JP"
web_1 | ]
web_1 | },
web_1 | "shipping_options": [
web_1 | {
web_1 | "shipping_amount": 500,
web_1 | "shipping_rate": "shr_1MdCMUF4dCXP6zukuuyKl0F7"
web_1 | }
web_1 | ],
web_1 | "shipping_rate": "shr_1MdCMUF4dCXP6zukuuyKl0F7",
web_1 | "status": "complete",
web_1 | "submit_type": null,
web_1 | "subscription": null,
web_1 | "success_url": "http://localhost:8000/orders/success",
web_1 | "total_details": {
web_1 | "amount_discount": 0,
web_1 | "amount_shipping": 500,
web_1 | "amount_tax": 0
web_1 | },
web_1 | "url": null
web_1 | }
しかし、ドキュメントには shipping というキーは存在しませんので、session オブジェクトに shipping_details
というキーが存在するのであれば shipping_details
が正しいと考えられます。
よって、書籍にも追記しました。
貴重なご指摘ありがとうございました。
今後ともよろしくお願いします!
決済処理の動作確認をしていますが、問題点が2つ出てきました
1つは、注文画面で注文内容の詳細が表示されないことです。書籍の画像では購入する商品の内容が詳しく分かりますが、自分の環境ではうまくいきません。なぜでしょうか?
2つ目は、購入完了後にカート内の商品が消去されず、在庫数も更新されないことです。
原因が分からず困っています。何かアドバイス頂けないでしょうか😭🙇♂️
def create
payload = request.body.read
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
endpoint_secret = Rails.application.credentials.dig(:stripe, :endpoint_secret)
event = nil
begin
event = Stripe::Webhook.construct_event(
payload, sig_header, endpoint_secret
)
rescue JSON::ParserError => e
# Invalid payload
p e
status 400
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
p e
status 400
return
end
case event.type
when 'checkout.session.completed'
session = event.data.object # sessionの取得
customer = Customer.find(session.client_reference_id)
return unless customer # 顧客が存在するかどうか確認
# トランザクション処理開始
ApplicationRecord.transaction do
order = create_order(session) # sessionを元にordersテーブルにデータを挿入
session_with_expand = Stripe::Checkout::Session.retrieve({ id: session.id, expand: ['line_items'] })
session_with_expand.line_items.data.each do |line_item|
create_order_details(order, line_item) # 取り出したline_itemをorder_detailsテーブルに登録
end
end
# トランザクション処理終了
customer.cart_items.destroy_all # 顧客のカート内商品を全て削除
redirect_to session.success_url
end
end
private
def create_order(session)
Order.create!({
customer_id: session.client_reference_id,
name: session.shipping.name,
postal_code: session.shipping.address.postal_code,
prefecture: session.shipping.address.state,
address1: session.shipping.address.line1,
address2: session.shipping.address.line2,
postage: session.shipping_options[0].shipping_amount,
billing_amount: session.amount_total,
status: 'confirm_payment'
})
end
def create_order_details(order, line_item)
product = Stripe::Product.retrieve(line_item.price.product)
purchased_product = Product.find(product.metadata.product_id)
raise ActiveRecord::RecordNotFound if purchased_product.nil?
order_detail = order.order_details.create!({
product_id: purchased_product.id,
price: line_item.price.unit_amount,
quantity: line_item.quantity
})
end
purchased_product.update!(stock: (purchased_product.stock - order_detail.quantity)) # 購入された商品の在庫数の更新
Rails.application.routes.draw do
devise_for :admins, controllers: {
sessions: 'admin/sessions'
}
devise_for :customers, controllers: {
sessions: 'customer/sessions',
registrations: 'customer/registrations'
}
root to: 'pages#home'
namespace :admin do
resources :products, only: %i[index show new create edit update]
end
scope module: :customer do
resources :products, only: %i[index show]
resources :cart_items, only: %i[index create destroy] do
member do
patch 'increase'
patch 'decrease'
end
end
resources :checkouts, only: [:create]
resources :webhooks, only: [:create]
end
get '/up/', to: 'up#index', as: :up
get '/up/databases', to: 'up#databases', as: :up_databases
get '/', to: 'pages#home'
end
ご質問頂きありがとうございます!
お待たせしてすみません。
本日中に対応させて頂きますのでもうしばらくお待ちください。
お待たせしました。
まず一つ目のバグから対応させて頂きます。
【注文画面で注文内容の詳細が表示されない件について】
決済画面で注文内容を表示する際には、app/controllers/customer/checkouts_controller.rb
の create_session
メソッド内で Stripe::Checkout::Session.create()
を実行しています。
したがって、こちらのコードにバグがある可能性があります。
app/controllers/customer/checkouts_controller.rb
のコードを見せていただいてもよろしいでしょうか。
返信ありがとうございます🙇♂️
以下、app/controllers/customer/checkouts_controller.rb のコードです。
よろしくお願いします
class Customer::CheckoutsController < ApplicationController
before_action :authenticate_customer!
def create
line_items = current_customer.line_items_checkout
session = create_session(line_items)
# Allow redirection to the host that is different to the current host
redirect_to session.url, allow_other_host: true
end
private
def create_session(line_items)
Stripe::Checkout::Session.create(
client_reference_id: current_customer.id,
customer_email: current_customer.email,
mode: 'payment',
payment_method_types: ['card'],
line_items:,
shipping_address_collection: {
allowed_countries: ['JP']
},
shipping_options: [
{
shipping_rate_data: {
type: 'fixed_amount',
fixed_amount: {
amount: 500,
currency: 'jpy'
},
display_name: 'Single rate'
}
}
],
success_url: "#{root_url}orders/success",
cancel_url: "#{root_url}cart_items"
)
end
end
ありがとうございます!
checkouts_controller.rb
の記述は大丈夫そうですね。
あとは、line_items_checkout
メソッドの記述について確認したいです。
GitHub に現在のコードを push していただけると助かります!
さきほど教材を完走しました!!
これだけ良質な教材が無料で利用できるのは感動です😭
最後に誤植と思われる箇所を記載いたします。
- 13章終盤 注文完了画面のを → 注文完了画面を
- 14章終盤 URLは http://localhost:8000/orders/1 ではなく http://localhost:8000/admin/orders/1 と思われます
- 20章
YouTubeのvideoIDが不正です
と出ています
以上です!ありがとうございました!
これからのFarStepさんの活動も応援しています📣
こんにちは。
最後まで本書籍をご覧頂きありがとうございました!
isosea さんには、本書籍に関するご質問・ご指摘をたくさん頂き、私自身も大変勉強になりました。
ありがとうございました。
誤植についてのご指摘もありがとうございます。こういったコメント非常に助かります 😭
先ほど全ての誤植を修正いたしました。
これからもみなさまのお役に立てるよう、努力していきたいと思います。
今後ともよろしくお願いします!
素晴らしい教材を作成いただきありがとうございました。
一点だけ、開発時に不満だった点があります。
決済時に、いちいちStripe CLIを起動させなければならない点です。教材を再開する際に何度か起動し忘れていたことがありました。
公式のドキュメントを見ると、Docker imageも配布されていますし、せっかくDockerで環境構築しているので、Stripe CLIもcomposeで起動させるようにしてみました。
教材の改善につながりますと幸いです!大変有益な書籍で勉強させていただきありがとうございます。
書籍についてご質問です。
購入完了後にカート内の商品が消去されず、在庫数も更新されない状況です。
原因が分からずアドバイスいただけますと幸いです。
class Customer::WebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
def create
payload = request.body.read
sig_header = request.env['HTTP_STRIPE_SIGNATURE']
endpoint_secret = Rails.application.credentials.dig(:stripe, :endpoint_secret)
event = nil
begin
event = Stripe::Webhook.construct_event(
payload, sig_header, endpoint_secret
)
rescue JSON::ParserError => e
# Invalid payload
p e
status 400
return
rescue Stripe::SignatureVerificationError => e
# Invalid signature
p e
status 400
return
end
case event.type
when 'checkout.session.completed'
session = event.data.object # sessionの取得
customer = Customer.find(session.client_reference_id)
return unless customer # 顧客が存在するかどうか確認
# トランザクション処理開始
ApplicationRecord.transaction do
order = create_order(session) # sessionを元にordersテーブルにデータを挿入
session_with_expand = Stripe::Checkout::Session.retrieve({ id: session.id, expand: ['line_items'] })
session_with_expand.line_items.data.each do |line_item|
create_order_details(order, line_item) # 取り出したline_itemをorder_detailsテーブルに登録
end
end
# トランザクション処理終了
customer.cart_items.destroy_all # 顧客のカート内商品を全て削除
redirect_to session.success_url
end
end
private
def create_order(session)
Order.create!({
customer_id: session.client_reference_id,
name: session.shipping.name,
postal_code: session.shipping.address.postal_code,
prefecture: session.shipping.address.state,
address1: session.shipping.address.line1,
address2: session.shipping.address.line2,
postage: session.shipping_options[0].shipping_amount,
billing_amount: session.amount_total,
status: 'confirm_payment'
})
end
def create_order_details(order, line_item)
product = Stripe::Product.retrieve(line_item.price.product)
purchased_product = Product.find(product.metadata.product_id)
raise ActiveRecord::RecordNotFound if purchased_product.nil?
order_detail = order.order_details.create!({
product_id: purchased_product.id,
price: line_item.price.unit_amount,
quantity: line_item.quantity
})
purchased_product.update!(stock: (purchased_product.stock - order_detail.quantity)) # 購入された商品の在庫数の更新
end
end
2023-08-25 23:04:22 --> charge.succeeded [evt_3Nj0caIzldJfiets1GPupOIp]
2023-08-25 23:04:22 --> checkout.session.completed [evt_1Nj0cbIzldJfietspTg1hpax]
2023-08-25 23:04:22 --> payment_intent.succeeded [evt_3Nj0caIzldJfiets13VkF5rE]
2023-08-25 23:04:22 --> payment_intent.created [evt_3Nj0caIzldJfiets1deusljC]
2023-08-25 23:04:22 <-- [204] POST http://localhost:8000/webhooks [evt_3Nj0caIzldJfiets13VkF5rE]
2023-08-25 23:04:23 <-- [204] POST http://localhost:8000/webhooks [evt_3Nj0caIzldJfiets1deusljC]
2023-08-25 23:04:23 <-- [500] POST http://localhost:8000/webhooks [evt_1Nj0cbIzldJfietspTg1hpax]
2023-08-25 23:04:23 <-- [204] POST http://localhost:8000/webhooks [evt_3Nj0caIzldJfiets1GPupOIp]
私も同じエラーで悩んでしましたが、
少し前のisoseaさんのコメントを参考に、
webhooks_controller.rbのcreate_orderメソッドの中で、shippingの部分をshipping_detailsに直すことで解決しました。
よければ、試してみてください。
ありがとうございます!
shipping_detailsに書き換えたところ作動しました!
すみません私も同じところでつまずいているのですが
こちらはwebhocks_controllerの中のOrder.createのshippingでいいのでしょうか?
def create_order(session)
Order.create!({
customer_id: session.client_reference_id,
name: session.shipping_amount.name,
postal_code: session.shipping_amount.address.postal_code,
prefecture: session.shipping_amount.address.state,
address1: session.shipping_amount.address.line1,
address2: session.shipping_amount.address.line2,
postage: session.shipping_options[0].shipping_amount,
billing_amount: session.amount_total,
status: 'confirm_payment'
})
end
ご返信が遅くなり大変申し訳ありません。
こちらのエラーが再現することを私の手元でも確認しました。
エラーの内容は下記の通りです。
- web-1 コンテナ(Rails アプリケーション)
NoMethodError (undefined method `shipping' for #<Stripe::Checkout::Session:0x7a44 id=cs_test_b1O2qVafNY1yDIaHlF5YS133UKETBhC9yp73gQdTOhYjKL4fS00IhDIsgD>
- localhost:8000/webhooks を Listen しているターミナル上
2024-01-06 12:30:04 --> charge.succeeded [evt_3OVQaEA8rEAY2MYv1EQBw5e8]
2024-01-06 12:30:04 <-- [204] POST http://localhost:8000/webhooks [evt_3OVQaEA8rEAY2MYv1EQBw5e8]
2024-01-06 12:30:04 --> payment_intent.succeeded [evt_3OVQaEA8rEAY2MYv1p6KUsQ2]
2024-01-06 12:30:04 <-- [204] POST http://localhost:8000/webhooks [evt_3OVQaEA8rEAY2MYv1p6KUsQ2]
2024-01-06 12:30:05 --> checkout.session.completed [evt_1OVQaGA8rEAY2MYv7ZqLntcx]
2024-01-06 12:30:05 <-- [500] POST http://localhost:8000/webhooks [evt_1OVQaGA8rEAY2MYv7ZqLntcx]
2024-01-06 12:30:05 --> payment_intent.created [evt_3OVQaEA8rEAY2MYv1gw41eAv]
2024-01-06 12:30:05 <-- [204] POST http://localhost:8000/webhooks [evt_3OVQaEA8rEAY2MYv1gw41eAv]
isosea さんや豆太郎 さんがおっしゃる通り Customer::WebhooksController
の create_order
メソッド内の session.shipping
を session.shipping_details
に修正することで、このエラーは解消されます。
つまり、下記のように修正してください。
def create_order(session)
Order.create!({
customer_id: session.client_reference_id,
name: session.shipping_details.name,
postal_code: session.shipping_details.address.postal_code,
prefecture: session.shipping_details.address.state,
address1: session.shipping_details.address.line1,
address2: session.shipping_details.address.line2,
postage: session.shipping_options[0].shipping_amount,
billing_amount: session.amount_total,
status: 'confirm_payment'
})
end
解決しない場合は、再度ご質問して頂けると幸いです。
何卒よろしくお願いします。
解決いたしました!!
ありがとうございます!
Stripeの勉強をしたいなと思っており、この書籍を見つけて勉強させていただいている最中です。
FarStep様には無料公開への感謝の念を隠しえません。本当にありがとうございます。
1点質問なのですが、現在決済処理を実装する章を読んでいるのですが、冒頭に決済が失敗した場合の処理を今回は省略しているとありますが、この点についての追記のご予定を伺いたいです。
また、こちらは自分でも調査するつもりではありますが、決済が失敗した場合の処理についてStripeのドキュメントがありましたらご教示頂きたいと存じます。
何卒よろしくお願いいたします。
大変貴重な教材ありがとうございます!
現在Stripeのセットアップの箇所でわからなくなっておりまして、
$ EDITOR="vi" bin/rails credentials:edit -e development
こちらのコマンドを実行してもviエディタが起動せず、調べて見たらDockerのコンテナ内でvimがインストールしていないのが原因とわかりましたが、vimのインストールの方法がわからなくて教えていただけますと幸いです。
試したこと
apt update
apt install -y vim
こちらのコマンドを実行してみましたが特にインストールされたりせずとなっております。
お手数をおかけいたしますがよろしくお願いいたします。
こんにちは。
丁寧にご質問して頂き誠にありがとうございます。
下記のコマンドを実行してみてください。
- root ユーザでコンテナに入る(パッケージをインストールするために root ユーザの権限が必要)
docker-compose run --rm -u root web bash
- vim をインストールする
apt-get update
apt-get install vim
ただし、この方法でインストールした vim は、コンテナを再起動するたびに消えてしまいます。
コンテナのビルドプロセス中に vim を永続的にインストールするには、下記のように Dockerfile を編集してください(本書の Chapter 05 にも記載されています)。
RUN apt-get update \
- && apt-get install -y --no-install-recommends build-essential curl libpq-dev \
+ && apt-get install -y --no-install-recommends build-essential curl libpq-dev vim \
&& rm -rf /var/lib/apt/lists/* /usr/share/doc /usr/share/man \
&& apt-get clean \
&& groupadd -g "${GID}" ruby \
&& useradd --create-home --no-log-init -u "${UID}" -g "${GID}" ruby \
&& chown ruby:ruby -R /app
解決しない場合は、再度ご質問して頂けると幸いです。
何卒よろしくお願いします。
おはようございます!
ご丁寧に教えていただきありがとうございます!
無事に解決できました!!
お忙しい中ご返信ありがとうございました!
引き続きよろしくお願いいたします!!!!
初めまして。
質問してもよろしいでしょうか。
現在Chapter7を終えたところでコミットし、pull requestを作成したところです。
すると、github actionで
./run ci:install-deps
の実行のタイミングに
0s
Run ls /usr/bin/bash
ls /usr/bin/bash
./run ci:install-deps
shell: /usr/bin/bash -e {0}
/usr/bin/bash
/home/runner/work/_temp/46b71ed3-f20d-4cb5-b6a9-bca64c42e969.sh: line 2: ./run: Permission denied
Error: Process completed with exit code 126.
とエラーが出てしまいました。
で調べたところによると、ファイルアクセス権限の問題のようで、ci.ymlにlsコマンドを追加しましたが結局原因がわからない状態です。
/home/runner/work/_temp/46b71ed3-f20d-4cb5-b6a9-bca64c42e969.sh
へのアクセスができていない、ということで認識はあっていますでしょうか。
またお手数ですが、解消方法をご教示いただけますと幸いです。
参考までに、PRへのリンクを掲載いたします。
よろしくお願いいたします。