0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Rails】購入等で一度入力した住所を次からは自動で入力,表示

Last updated at Posted at 2021-03-30

スクリーンショット 2021-03-30 20.46.56.png
以前住所を入力したので、このようにまだ何も入力してませんが、すでに値が入っています

今回は、ユーザーが住所を入力して商品を購入した時に、次からは、その住所を使い回す的な機能を実装していきます

従来の問題

今までは、ユーザーの情報と、住所の情報が紐付いてなくて、商品を購入するたびに、いちいち住所を入力しなければならず、使い勝手が悪いアプリでした。

ユーザーと住所を紐付ける

何はともあれ、このような機能を実装するには、ユーザーと住所を紐付けないといけないので、紐付けていきます

スクリーンショット 2021-03-30 20.38.34.png

住所の情報が入ったaddressesテーブルです。
ここにuser_idとかいう外部キーを入れて、ユーザーと住所を紐付けたりします。

外部キーのカラムの追加の仕方は今回は割愛。
ググったら出てきます

アソシエーションを組む

user.rb

has_one: address

address.rb

belongs_to: user

ユーザーが親ですね。住所っていうのはユーザーあってのものなので(説明が適当すぎてすいません)

一つのビューで複数のテーブルに値を保存する処理を書く

trades_controller.rb

  def index
    # 購入ページ

    @item = Drink.find(params[:drink_id])
    @order = TradeAddress.new
    @user_address = current_user.address 
  
  end

  def new

    @item = Drink.find(params[:drink_id])
    @order = TradeAddress.new
    # 商品購入ページ
  end

  def create

    @item = Drink.find(params[:drink_id])
    @order = TradeAddress.new(trade_params)
    if @order.valid?
      pay_item
      @order.save
    else
      render 'index'
    end
  end

trade_address.rb

class TradeAddress
  include ActiveModel::Model
  include ActiveRecord::AttributeAssignment
  include SessionsHelper
  # form_withやrender等の色々な機能が使える
  attr_accessor :fam_name,:first_name,:fam_name_kana,:first_name_kana,:birthday,:postal_code, :city, :house_num, :building_name, :phone_num, :drink_id, :prefecture_id,:trade_id, :user_id, :price,:token,:authenticity_token,:number,:exp_month,:exp_year,:cvc,:commit

  with_options presence: true do

    with_options format: { with: /\A[ぁ-んァ-ン一-龥]/, message: 'は全角で入力してください。' } do
      validates :fam_name
      validates :first_name
    end

    with_options format: { with: /\A[ァ-ヶー-]+\z/, message: 'は全角カタカナで入力して下さい。' } do
    validates :fam_name_kana
    validates :first_name_kana
    end

    validates :birthday
    validates :postal_code,format: {with: /\A\d{3}[-]\d{4}\z/}
    validates :prefecture_id, numericality: { other_than: 1 } 
    validates :city
    validates :house_num
    validates :phone_num
    validates :token
  end


  def save
    
    trade = Trade.create(user_id: user_id, drink_id: drink_id)

    Address.create(fam_name: fam_name,first_name: first_name,fam_name_kana: fam_name_kana,first_name_kana: first_name_kana,postal_code: postal_code, prefecture_id: prefecture_id, birthday: birthday,city: city, house_num: house_num, building_name: building_name, phone_num: phone_num, trade_id: trade.id,user_id: user_id)
  end
end

複数テーブルに値を保存するFormsヘルパーの使い方についても割愛

trades/index.html.erb

かなり冗長なコードですが、
@user_addressがあったら、value: @user_address.first_nameみたいに、
初期値をセットすると言ったやり方です

フォームとかにvalue: hoge
とかやったりすると、そのフォームにすでにhogeと入力されてる状態となっております

ちなみに、select系のフォームは
selectedとかで初期値をセットしてます。
下に具体的なコードを書いてるのでぜひ見てください
ってか、馬鹿みたいに冗長ですね。
form_withがそこら辺をよしなにやって欲しかったのですが、何ともできなかった。。。。

<% if  @user_address%>
  

<div class='transaction-contents'>
  <div class='transaction-main'>
    <h1 class='transaction-title-text'>
      購入内容の確認
    </h1>
    <%# 購入内容の表示 %>
    <div class='buy-item-info'>
      <%= image_tag @item.image, 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'>¥<%= @item.price %></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'>
        ¥<%= @item.price %>円
      </p>
    </div>
    <%# /支払額の表示 %>
    <%= render 'shared/error_messages', object: @order %>
    <%= 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>

      <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="user-address">
      <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 :fam_name, class:"input-default", id:"postal-code",placeholder:"例) 原",value: @user_address.fam_name %>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">名前</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :first_name, class:"input-default", id:"postal-code" ,placeholder:"例) 奏一郎",value: @user_address.first_name %>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">苗字カナ</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :fam_name_kana, class:"input-default", id:"postal-code" ,placeholder:"例) ハラ",value: @user_address.fam_name_kana %>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">名前カナ</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :first_name_kana, class:"input-default", id:"postal-code",placeholder:"例) ソウイチロウ",value: @user_address.first_name_kana %>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">生年月日</label>
          <span class="indispensable">必須</span>
        </div>

          <%= raw sprintf(
                    f.date_select(
                      :birthday,
                      class:'select-box',
                      id:"birth-date",
                      use_month_numbers: true,
                      prompt:'--',
                      start_year: 1945,
                      selected: @user_address.birthday ,
                      end_year: (Time.now.year - 5),
                      date_separator: '%s'),
                    "<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>
      </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 :postal_code, class:"input-default", id:"postal-code", placeholder:"例)123-4567(ハイフンを含めてください)", maxlength:"8" ,value: @user_address.postal_code %>
      </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,{selected: @user_address.prefecture_id }, {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 :city, class:"input-default", id:"city", placeholder:"例)武蔵村山市星野区",value: @user_address.city %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">番地</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :house_num, class:"input-default", id:"addresses", placeholder:"例)神明1-1-1",value: @user_address.house_num %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">建物名</label>
          <span class="form-any">任意</span>
        </div>
        <%= f.text_field :building_name, class:"input-default", id:"building", placeholder:"例)立川ビル801",value: @user_address.building_name %>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">電話番号</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :phone_num, class:"input-default", id:"phone-number", placeholder:"例)09012345678",maxlength:"11",value: @user_address.phone_num %>
      </div>
    </div>
    <%# /配送先の入力 %>
    <div class='buy-btn'>
      <%= f.submit "購入" ,class:"buy-red-btn",id: "buy-red-btn" %>
    </div>
    <% end %>
  </div>
</div>



<% else %>
<div class='transaction-contents'>
  <div class='transaction-main'>
    <h1 class='transaction-title-text'>
      購入内容の確認
    </h1>
    <%# 購入内容の表示 %>
    <div class='buy-item-info'>
      <%= image_tag @item.image, 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'>¥<%= @item.price %></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'>
        ¥<%= @item.price %>円
      </p>
    </div>
    <%# /支払額の表示 %>
    <%= render 'shared/error_messages', object: @order %>
    <%= 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>

      <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="user-address">
      <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 :fam_name, class:"input-default", id:"postal-code",placeholder:"例) 原"%>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">名前</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :first_name, class:"input-default", id:"postal-code" ,placeholder:"例) 奏一郎"%>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">苗字カナ</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :fam_name_kana, class:"input-default", id:"postal-code" ,placeholder:"例) ハラ"%>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">名前カナ</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :first_name_kana, class:"input-default", id:"postal-code",placeholder:"例) ソウイチロウ"%>
      </div>

      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">生年月日</label>
          <span class="indispensable">必須</span>
        </div>
                <%= raw sprintf(
                    f.date_select(
                      :birthday,
                      class:'select-box',
                      id:"birth-date",
                      use_month_numbers: true,
                      prompt:'--',
                      start_year: 1945,
                      end_year: (Time.now.year - 5),
                      date_separator: '%s'),
                    "<p> 年 </p>", "<p> 月 </p>") + "<p> 日 </p>" %>
      </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 :postal_code, 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 :city, 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 :house_num, 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 :building_name, class:"input-default", id:"building", placeholder:"例)立川ビル801"%>
      </div>
      <div class="form-group">
        <div class='form-text-wrap'>
          <label class="form-text">電話番号</label>
          <span class="indispensable">必須</span>
        </div>
        <%= f.text_field :phone_num, class:"input-default", id:"phone-number", placeholder:"例)09012345678",maxlength:"11"%>
      </div>
    </div>
    <%# /配送先の入力 %>
    <div class='buy-btn'>
      <%= f.submit "購入" ,class:"buy-red-btn",id: "buy-red-btn" %>
    </div>
    <% end %>
  </div>
</div>

<% end %>
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?