0W5E8fPq1EOm4yE
@0W5E8fPq1EOm4yE (Nishio)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

フリマアプリ購入機能実装について

解決したいこと

現在フリマアプリの購入機能を実装しているのですがNameErrorと出てしまいましたどうしたらよろしいでしょうか?

発生している問題・エラー

![スクリーンショット 2020-12-20 22.26.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/832099/07bc269a-067c-4584-f01b-5cabcad46964.png)

class AddressesController < ApplicationController

  def index
  end

  def new
    @address = Address.new
  end

  def create

    @address = Address.new(address_params)
    if @address.valid?
      pay_item
      @address.save
      return redirect_to root_path
    else
      render 'index'
    end
  end

  private

  def address_params
    params.require(:address).permit(:token, :post_number, :prefecture_id, :municipality, :address, :build_name, :phone_number).merge(user_id: current_user.id,item_id:params[:item_id])
  end

end


該当するソースコード

class PurchasesController < ApplicationController

  def index
    @purchase = Purchase.new
  end

  def create
    binding.pry
    @purchase= Purchase.create(purchase_params)
    Address.create(address_params(purchase))
    Item.create(item_params(purchase))
    if @purchase.valid?
     pay_item
      @purchase.save
      return redirect_to root_path
    else
      render 'index'
    end
  end

  private

  def purchase_params
    params.require(:purchase).permit(:user_id, :item_id)
  end

  def address_params(purchase)
    params.require(:address).permit(:token, :post_number, :prefecture_id, :municipality, :address, :build_name, :phone_number)
  end

  def item_params
    params.require(:item).permit(:name, :text, :price, :state_id, :category_id, :prefecture_id, :burden_id, :shippingday_id, :image).merge(user_id: current_user.id)
  end

  def pay_item
    Payjp.api_key = ENV["PAYJP_SECRET_KEY"]
    Payjp::Charge.create(
      amount: item_params[:price],
      card: purchase_params[:token],
      currency:'jpy'
    )
  end

end
class Address < ApplicationRecord
  with_options presence: true do
    validates :post_number, format: { with: /A\d{3}[-]\d{4}z/, message: 'Input correctly' }
    validates :municipality
    validates :prefecture_id, numericality: { other_than: 1, message: 'Select' }
    validates :address
    validates :phone_number, format: { with: /A\d{11}z/, message: 'Input only number' }
    validates :token
  end
  belongs_to :purchase
end```

```言語名←入力するとソースコードにシンタックスハイライトが付きます
class PurchaseAddress < ApplicationRecord
  attr_accessor :token
  validates :token, presence: true
  has_one :purchase
end
<%= form_with(model: @purchase, url: purchases_path, local: true) do |form| %>
<%= render "shared/second-header"%>

<div class='transaction-contents'>
  <div class='transaction-main'>
    <h1 class='transaction-title-text'>
      購入内容の確認
    </h1>
    <%# 購入内容の表示 %>
    <div class='buy-item-info'>
      <%= image_tag "item-sample.png", class: 'buy-item-img' %>
      <div class='buy-item-right-content'>
        <h2 class='buy-item-text'>
          <%= 'item.name' %>
        </h2>
        <div class='buy-item-price'>
          <p class='item-price-text'>¥<%= '999,999,999' %></p>
          <p class='item-price-sub-text'><%= '配送料負担' %></p>
        </div>
      </div>
    </div>
    <%# /購入内容の表示 %>

    <%# 支払額の表示 %>
    <div class='item-payment'>
      <h1 class='item-payment-title'>
        支払金額
      </h1>
      <p class='item-payment-price'>
        ¥<%= "販売価格" %>
      </p>
    </div>
    <%# /支払額の表示 %>

    <%= form_with  id: 'charge-form', class: 'transaction-form-wrap',local: true do |f| %>
    <%# カード情報の入力 %>
    <div class='credit-card-form'>
      <h1 class='info-input-haedline'>
        クレジットカード情報入力
      </h1>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">カード情報</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :number, class:"input-default", id:"card-number", placeholder:"カード番号(半角英数字)", maxlength:"16" %>
        <div class='available-card'>
          <%= image_tag 'card-visa.gif', class: 'card-logo'%>
          <%= image_tag 'card-mastercard.gif', class: 'card-logo'%>
          <%= image_tag 'card-jcb.gif', class: 'card-logo'%>
          <%= image_tag 'card-amex.gif', class: 'card-logo'%>
        </div>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">有効期限</label>
          <span class="indispensable">必須</span>
        </div>
        <div class='input-expiration-date-wrap'>
          <%= f.text_area :exp_month, class:"input-expiration-date", id:"card-exp-month", placeholder:"例)3" %>
          <p>月</p>
          <%= f.text_area :exp_year, class:"input-expiration-date", id:"card-exp-year", placeholder:"例)23" %>
          <p>年</p>
        </div>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">セキュリティコード</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :cvc,class:"input-default", id:"card-cvc", placeholder:"カード背面4桁もしくは3桁の番号", maxlength:"4" %>
      </div>
    </div>
    <%# /カード情報の入力 %>

    <%# 配送先の入力 %>
    <div class='shipping-address-form'>
      <h1 class='info-input-haedline'>
        配送先入力
      </h1>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">郵便番号</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :post_number, class:"input-default", id:"postal-code", placeholder:"例)123-4567", maxlength:"8" %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">都道府県</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {}, {class:"select-box", id:"prefecture"}) %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">市区町村</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :municipality, class:"input-default", id:"city", placeholder:"例)横浜市緑区"%>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">番地</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :address, class:"input-default", id:"addresses", placeholder:"例)青山1-1-1"%>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">建物名</label>
          <span class="form-any">任意</span>
        </div>
        <%= f.text_field :build_name, class:"input-default", id:"building", placeholder:"例)柳ビル103"%>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">電話番号</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :phone_number, class:"input-default", id:"phone-number", placeholder:"例)09012345678",maxlength:"11"%>
      </div>
    </div>
    <%# /配送先の入力 %>
    <div class='buy-btn'>
      <%= f.submit "購入" ,class:"buy-red-btn" %>
    </div>
    <% end %>
    <% end %>
  </div>
</div>
<%= render "shared/second-footer"%>

自分で試したこと

ビューにform_withの記述をしてparamsを渡すようにした。
binding.pryでデバッグをした。

0

2Answer

Purchase クラスが未定義のようです。app/models/purchase.rb は存在してますか?

0Like

Comments

  1. 存在してます!モデルの中身がPurchaseAddressになっていたのでPurchaseに変更しました。

おそらく、Formオブジェクトを使用してpurchaseテーブルとaddressテーブルに同時にテータを保存する仕様になってると思いますが、いかがでしょうか?
もしそうであれば、PurchaseモデルとAddressモデルでアソシエーションを設定して、PurchaseAddressクラスで両テーブルのデータを保存する記述をする必要があります。
もう一度ご確認いただければと思います。

0Like

Comments

  1. Formオブジェクトを使用してpurchaseテーブルとaddressテーブルに同時にテータを保存する仕様にするつもりです!
  2. あと、form_withがビューファイルの先頭に追加してありますが、35行目付近にform_withの雛型があるので、こちらを使うといいと思います。
    このとき指定するモデルは、formオブジェクトで作成したモデルになります。
  3. formオブジェクトで作成したモデルはこちらになります
    class PurchaseAddress < ApplicationRecord
    extend ActiveHash::Associations::ActiveRecordExtensions
    include ActiveModel::Model
    attr_accessor :post_number, :municipality, :prefecture_id, :address, :phone_number, :user_id, :item_id, :token


    belongs_to :prefecture



    with_options presence: true do
    validates :post_number, format: { with: /A\d{3}[-]\d{4}z/, message: 'Input correctly' }
    validates :municipality
    validates :prefecture_id, numericality: { other_than: 1, message: 'Select' }
    validates :address
    validates :phone_number, format: { with: /A\d{11}z/, message: 'Input only number' }
    validates :token
    end

    def save
    Purchase.create(user_id: user_id, item_id: item_id)
    Address.create(post_number: post_number, municipality: municipality, prefecture_id: prefecture_id, address: address, phone_number: phone_number, user_id: user_id, address_id: address_id)
    Item.create(name: name, text: text, price: price, state_id: state_id, category_id: category_id, prefecture_id: prefecture_id, burden_id: burden_id, shippingday_id: shippingday_id, image: image, user_id: current_user.id)
    end
    end
  4. Address.createの中に、user_idとaddress_idがありますが、Addressesテーブルにこれらのカラムは存在していますか?
  5. Addressesテーブルにはuser_idのみですのでaddress_idは削除しました。
  6. それですと、PurchaseAddressテーブルに、Purchaseテーブルのuser_idと、Addressテーブルのuser_idがダブルで存在することになるのですが、Addressテーブルのuser_idは必要でしょうか?
  7. あと、修正していくうちにparam is missing or the value is empty: addressと出てしまいました。

Your answer might help someone💌