PF作成：１４日目

今日は予定外の外出で学習時間の確保が難しかったのと、問題解決に予想以上に時間がかかってしまったためあまり勧められなかった。明日、頑張って取り返そう。

## 進捗
- 現在までに発生していた問題解決
- ログインしているユーザー本人しか閲覧することができない御朱印投稿一覧が表示される参拝日記
- 御朱印の編集、削除機能（ログインしているユーザー本人しか出現しない）
- レイアウトを少し整えた


## 学習
### 【レイアウト】
- ユーザーアイコンを使用しようと考え、形は丸にしようとネットで検索。Bootstrapで画像を丸く表示するコードを発見。<br>画像を呼び出しているコードにrounded-circleを指定してあげるだけでOK。<br>（参考資料：https://lightgauge.net/bootstrap/rounded-circle)
- ヘッダーに存在してるロゴを中央寄せにしたいと思いいろいろ試したが、結果できなかった。そのためメンターさんに手伝ってもらい成功したが、あまりにいろいろなことをやりすぎてどこがどうかわからなくなってしまった。Bootstrapで全て構成されていたが、奥が深くてすごい。

### 【機能】
- JavaScriptで選択した画像をすぐにページに反映させるコードを記述したが、見直した時に別のjsファイルに入り込んでしまっていたのでapplication.jsに戻したが機能しなくなってしまった。<br>原因はファイルを移動した時に消したコードがapplication.jsに記述するなら必要だったみたいで、その記述がない所為で機能しなくなった。１行足しただけで機能復活。<br>
```ruby:app/JavaScript/packs/application.js
$(document).on('turbolinks:load', function() {
  // 画像アップロードフィールドの変更イベントが発生したときの処理
  $('#imageField').on('change', (e) => {
    // 選択されたファイルを取得
    var file = e.target.files[0];
    // FileReaderオブジェクトを作成
    var reader = new FileReader();
    // 読み込み完了時の処理
    reader.onload = (f) => {
      // プレビュー画像のsrc属性を選択した画像ファイルのDataURLに設定
      $('#imagePreview').attr('src', f.target.result);
    }
    // 画像ファイルをDataURL形式で読み込む
    reader.readAsDataURL(file);
  });
```
$(document).on('turbolinks:load', function() {　この記述を追加

- ログアウト状態でも閲覧許可するコードを忘れてしまった。答えは簡単でbefore_actionコードの後にexcept: [:許可したいメソッド]を記述するだけ。before_actionがアクセス制限なので制限をかけた後except: [:許可したいメソッド]を記述してあげることによってアクセス制限が外れる。ちなみに逆に特定のメソッドにアクセス制限をかけたい場合はonliy

## エラー
- 画像背景が一部のページだけ画面全体を覆えていなかった。どうして一部のページだけそうなるのかわからず、メンターさんに聞いてもわからなかった。けど前にちょこちょこ表示させない内容がフッターの下に表示されてしまったりテーブルから外れることがあったことを思い出して、その時の原因が閉じタグやインデントがおかしいことが多かったので、問題のviewページを確認。思った通りで</div>が一つ多く存在していた。消して確認したら背景画像が全面覆えたことを確認した。タグやインデントには気をつけよう。

- ユーザー詳細編集で更新ボタンを押すとルーティングエラーが起きていた。editのviewで編集した内容がupdateに渡せないということでルーティングエラーが起きていた。原因はform_withの記述が間違っていた。<br>
```ruby:app/view/user/users/edit/html.erb
<div class="col-md-7 offset-lg-1">
      <h2>ゆぅざぁ編集</h2>
       <!--間違い-->
      <%#= form_with model: @user, url: users_maypage_path, method: :patch do |f| %>
      <%= form_with model: @user, url: users_information_path, method: :patch do |f| %>
        <!--バリデーションの部分テンプレート-->
        <!--formからmodelobjectを抜き出す-->
        <%= render "layouts/error_messages", model: f.object %>

        <div class="form-group">
          <!--画像サイズのブートストラップ-->
          <div class="w-50">
            <!--画像カラムが空かどうか判断-->
            <% if @user.image.attached? %><!--入っていた場合-->
              <%= image_tag @user.image, style: "max-width: 200px;", id: 'imagePreview', class: "img-fluid mb-3" %>
            <% else %><!--入っていない場合-->
              <%= image_tag "profile_no_image", id: 'imagePreview', class: "img-fluid mb-3" %>
            <% end %>
          </div>
           <%= f.file_field :image, id: "imageField" %>
        </div>

    　   <div class="form-group mt-3">
          <%= f.label :にっくねぇむ %>
          <%= f.text_field :nickname, class: "form-control" %>
        </div>

        <%= f.submit '編集' %>
      <% end %>
    </div>
```
updateに渡すからupdateのurlを記述しなければいけないところをshowのurlを記述していた。showは遷移先だから間違っていた。

- ログアウト状態で別のユーザーのマイページに移動しようとしたらメソッドエラーが発生した。nilで。<br>原因はすぐに判断できて、userコントローラーのshowがマイページ関連で記述が<br>
```ruby:app/controllers/user/users-controller.rb
class User::UsersController < ApplicationController

  # ユーザーマイページ。誰でも閲覧可能
  def show
    @user = current_user
    @goshuins = @user.goshuins.page(params[:page]).per(10) # ページネーションを適用（１ページ１０件表示）
    @goshuin_names = @goshuins.map { |goshuin| goshuin.place.name }
    @goshuin_users = @goshuins.map { |goshuin| goshuin.user.nickname }
    @goshuin_prefectures = @goshuins.map { |goshuin| goshuin.place.prefecture }
  end

  # プロフィール編集
  def edit
    @user = current_user
  end
  
  def update
    @user = current_user
    if @user.update(user_params)
      redirect_to users_mypage_path(@user)
      flash[:notice] = "編集されました"
    else
      flash.now[:alert] = "失敗しました"
      render :edit
    end
  end

  private

  def user_params
    params.require(:user).permit(:id, :nickname, :email)
  end

end
```
@user = current_userが原因。@user = current_userで＠userにユーザーの情報を入れて＠goshuinsに＠userを入れてあげることで関連づけてそのユーザーが投稿した一覧ページを表示させるような仕組みを作ったつもりだったが、@user = current_userだとログインしている本人のデータした渡せないからログインしていなくても誰でも閲覧可能という仕組みと違うことをしてしまっていた。<br>解決方法は自分一人ではできなかったのでメンターさんに教わりながらやった。<br>まずはルーティングをいじって、<br>
```ruby:config/routes.rb
scope module: :user do
    root "homes#top"
    # マイページ
    get 'users/mypage/:id' => 'users#show', as: :users_mypage
    # 会員編集ページ
    get 'users/infomation/edit' => 'users#edit'
    patch '/users/information' => 'users#update'
    # 退会確認ページ
    get 'users/confirm_withdraw' => 'users#confirm_withdraw'
    # 退会機能
    patch '/customers/withdraw' => 'customers#withdraw'
    resources :places, only: [:new, :create, :index, :show, :edit, :update]
    resources :goshuins, only: [:new, :create, :index, :edit, :update, :destroy]
  end
```
get 'users/mypage/:id' => 'users#show', as: :users_mypageここを変更。ルーティングにuser_idを持たせてas:を使用してルーティング名を決定。<br>先ほどのコントローラーの記述を@user = current_userから@user = User.find(params[:id])に変更。<br>
```ruby:app/controllers/user/users-controller.rb
class User::UsersController < ApplicationController

  # ユーザーマイページ。誰でも閲覧可能
  def show
    @user = User.find(params[:id])
    @goshuins = @user.goshuins.page(params[:page]).per(10) # ページネーションを適用（１ページ１０件表示）
    @goshuin_names = @goshuins.map { |goshuin| goshuin.place.name }
    @goshuin_users = @goshuins.map { |goshuin| goshuin.user.nickname }
    @goshuin_prefectures = @goshuins.map { |goshuin| goshuin.place.prefecture }
  end

  # プロフィール編集
  def edit
    @user = current_user
  end
  
  def update
    @user = current_user
    if @user.update(user_params)
      redirect_to users_mypage_path(@user)
      flash[:notice] = "編集されました"
    else
      flash.now[:alert] = "失敗しました"
      render :edit
    end
  end

  private

  def user_params
    params.require(:user).permit(:id, :nickname, :email)
  end

end
```

これによって対応したユーザーのマイページへ遷移できるようになった。最後にviewで<br>
```ruby:app/views/layouts/_goshuin_index.html
<!-- ユーザーの御朱印一覧表示 -->
<div class="mb-3">
  <% goshuins.each do |goshuin| %>
    <div class="card-body">
      <p class="card-text">
        <div class="d-flex justify-content-between">
          <div>
            <!-- ユーザーのマイページへのリンク -->
            <%= link_to goshuin.user.nickname, users_mypage_path(id: goshuin.user.id), class: "user-profile-link" %><br>
            <%= goshuin.place.prefecture.name %>
          </div>
          <h5 class="card-title text-center">
            <%= link_to place_path(goshuin.place) do %>
              <%= goshuin.place.name %>
            <% end %>
            <% if admin_signed_in? %>
              <%= link_to admin_place_path(goshuin.place) do %>
                <%= goshuin.place.name %>
              <% end %>
            <% end %>
          </h5>
          <div class="card-text">
            心付け：￥<%= goshuin.price %><br>
            参拝日：<%= goshuin.visit_day %>
          </div>
        </div>
      </p>
      <div class="card-img-bottom">
        <%= image_tag goshuin.get_goshuin_image, alt: 'Place Image', width: 100, height: 100 %>
      </div>
      <p class="card-text mb-5">
        <%= goshuin.message %>
      </p>
      <div>
        <!--ユーザーがログインしていて、かつ本人であった場合のみ表示される-->
        <% if user_signed_in? && goshuin.user == current_user %>
          <%= link_to "編集", edit_goshuin_path(goshuin), class: "btn btn-sm btn-info mt-3" %>
          <%= link_to "削除", goshuin_path(goshuin), method: :delete, data: { confirm: "本当に削除してもいいですか?" }, class: "btn btn-sm btn-danger" %>
        <% end %>
      </div>
    </div>
  <% end %>
</div>

<!-- ページネーション -->
<div class="d-flex justify-content-center">
  <div class="pagination">
    <%= paginate goshuins %>
  </div>
</div>
```

<%= link_to goshuin.user.nickname, users_mypage_path(id: goshuin.user.id), class: "user-profile-link" %>ここが重要。ほとんどいつも通りで、私が間違えたところはやっぱりというかなんというか引数。(id: goshuin.user.id)id:で対応したuser_idを取ってきてそれに関連している御朱印データを取ってきてuser.idそのuser_idも持ってくるというもの。<br>ここまで長かったけどここまでできれば今回のエラーは解決できた。ただ、ルーティングを変更してあげないといけないのは全く想像つかなかった。

## 明日の予定
御朱印を投稿する時に全体表示にするか非表示にするかの機能に取り掛かって、マイページには全体表示にした投稿を表示させるようにして、参拝日記には表示、非表示関係なく御朱印投稿一覧が表示されるようにする。参拝日記ボタン自体をログインしているユーザのみ表示される仕組みを作っているのでおそらくそれで可能だと思う。できたら完成まで持っていきたい。