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

![スクリーンショット 2021-03-30 20.46.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653881/82cea673-d431-e34b-e087-86e9ce0a2c33.png)
**以前住所を入力したので、このようにまだ何も入力してませんが、すでに値が入っています**

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

# 従来の問題

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

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

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

![スクリーンショット 2021-03-30 20.38.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653881/dc3daa71-424a-2738-dc4a-6cbfb5218e5a.png)

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

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

# アソシエーションを組む

**user.rb**

```
has_one: address
```

**address.rb**

```
belongs_to: user
```

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

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

**trades_controller.rb**

```ruby
  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**

```ruby
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がそこら辺をよしなにやって欲しかったのですが、何ともできなかった。。。。

```ruby
<% 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 %>
```