TECH 　DAY　7

勉強した項目：　git, Github, scraping
時間： 10:30
内容：

＊学習アウトプットです。なにぶん間違いなんかもあります。気をつけますがその際はご指摘いただけますと幸いです＊

###[リダイレクト]
本来アクセスしたページとは別のページへ移動すること
`redirect_to`というメソッドでリダイレクトさせることができる、また`action`オプションを使用することで特定のアクションを指定することが可能

```ruby
redirect_to action: アクション名
```


```ruby:例
def create
    # Review.create(create_params)
    redirect_to controller: :apps, action: :index
end
```

###[requireメソッド]
form_forに入力されたデータはparamsの中に以下のような形でコントローラに送るメソッド

```erb:new.html.erb
<%= form_for(@app) do |f| %>
  <%= f.text_field :name %>
  <%= f.text_area :detail %>
<% end %>
```

```ruby:ターミナル
params
# { app: { name: "入力された名前", detail: "入力された詳細" } }
```

```ruby:例/apps_controller.rb
params
# { app: { name: "入力された名前", detail: "入力された詳細" } }
params.require(:app)
# => { name: "入力された名前", detail: "入力された詳細" }
```

###[form_tag]
`params`は、ビューファイルのフォームで与えた`name属性`が`キー`となっている
それぞれの`キー`に対して、入力した情報が`値`として紐付いている
このハッシュ構造を生成する`form_tag`では、`params.permit(:キー名)`で取得できる

###[form_for]
`params`は、ハッシュの中にハッシュが存在する`二重構造`になっている
`review`というキーに対応する値そのものが`ハッシュ`だからであり、そのハッシュの中には、`カラム名がキー`となり、入力した情報が値として紐付いている。
このハッシュ構造を生成する`form_for`では、`params.require(:モデル名).permit(:カラム名)`で入力した情報が取得できる

**paramsのハッシュ構造の違いによって、入力した情報の保存方法も変わる**

###[mergeメソッド]
mergeメソッドは2つのハッシュを統合する時に使うメソッド

```ruby:例
hash1 = {question: "Who is your favorite artist?"}
hash2 = {group: "alulike", name: "taka"}
hash1.merge(hash2)
#=> {:question=>"Who is your favorite artist?", :group=>"alulike", :name=>"taka"}
```

ストロングパラメーターはpermitを用いているので取得できる

```ruby:/reviews_controller.rb
def create_params
  params.require(:review).permit(:name, :rate, :review).merge(app_id: params[:app_id])
end
```

```ruby:/reviews_controller.rb
Review.create(create_params)
```

###[erb記法でRailsのオブジェクトの値をHTML内に入れるには]

```erb
<%= 変数 %> # Railsの変数をHTML内に埋め込む
```

###[ActiveRecord Relationクラス]
whereメソッドやアソシエーションを利用してDBから複数のレコードをインスタンスとして取得した場合、取得した配列はActiveRecord Relationクラスに属する

```ruby:例
apps = App.all
  apps.class #=> ActiveRecord::Relation::ActiveRecord_Relation_App
```

`class`メソッドを利用すると、利用したインスタンスが属するクラスを確認できる
これはあくまでも `class` というメソッド

###[averageメソッド]
これもaverageメソッド　→`average`メソッドを利用するインスタンス取得先のテーブルのカラムをシンボル型で引数にとり、その値の平均を、`小数点ありの状態`で返す

```ruby:例
athletes = Athlete.all
  athletes.average(:score)
  #=> 小数点まで含んだ平均点
```

###[roundメソッド]
小数点ありの数字クラスのインスタンスが利用でき,利用した数字の小数点以下を四捨五入してくれる

```ruby:例
10.4.round
  #=> 10

10.5.round
  #=> 11
```

###[present?]
`present?`メソッドは、配列の中身が存在すれば`true`、存在しなければ`false`を返すメソッド
if文と組み合わせて使用する

```erb:例
  <% if app.reviews.present? %>
    <span class="rating-star">
      <i class="star-actived rate-<%= product.reviews.average(:rate).round %>0"></i>
    </span>
  <% else %>
    <span class="rating-star">
      <i class="star-actived rate-0"></i>
    </span>
  <% end %>
```

###[レシーバ]
インスタンスメソッドを利用するインスタンス自身のこと

```ruby:例
  str = "3"
  #以下の式のレシーバはstr
  str.to_i #=> 3
```
3行目の式におけるレシーバはstr

###[self]
インスタンスメソッドの中でselfと書くと、そのメソッドを利用したレシーバ自身が代入された変数のように扱うことができる
Integerクラスに定義されているインスタンスメソッド、odd?を例にしてみるとする。
→odd?はレシーバが奇数かどうかを判定してtrueかfalseを返してくれるインスタンスメソッドのこと

```ruby:例
  class Integer
    def odd?
      if self % 2 == 1
        return true
      else
        return false
      end
    end
  end
  2.odd? #=> false(%は剰余を求めるもので、余りが1ではないのでfalseが返ってくる)
```
###[before_action]
全てのアクションが実行される前に指定したメソッドを呼び出すことができるもの

```ruby:例
  class コントローラ名 < ApplicationController
    before_action :処理させたいメソッドの名前
```
before_actionの特徴
① before_actionを書いたコントローラのすべてのアクションの前に処理を行える
② before_actionを書いたコントローラで共通の処理を行える

###[コントローラの継承]
コントローラは別のコントローラを継承することができる
　→元のコントローラの持つメソッドや特徴を引き継ぐことができる

```ruby:
class コントローラ < 継承元のコントローラ
end
```

```ruby:例
class CatController < AnimalController
end
```

```ruby:例
class AnimalController < ApplicationController
  before_action :say_hello

  def say_hello
    puts "Hello Animal"
  end
end
```

すると

```ruby:例２
class CatController < AnimalController
  def show
    @cat = Cat.find(params[:id])
  end
end

# => showアクションの前にsay_helloが呼ばれる
```

これは、`AnimalController`を継承した`CatController`のすべてのアクションの前にも`before_action`の`say_helloメソッド`が呼ばれます。

すべてのコントローラで共通の`before_action`を定義したい場合は`ApplicationController`記述するのは、
`すべてのコントローラ`(ApplicationController以外)が`ApplicationController`を継承しているためである

###[レイアウトファイル]
`app/views/layouts/`の下に入っている`HTMLファイル`
→URLにアクセスして対応するコントローラが呼ばれたあと、`最初に表示されるHTML`のこと

###[layout 'レイアウトファイル名']
コントローラ内で`layout 'レイアウトファイル名'`と書くと、そのコントローラでのアクションが呼ばれたあと表示するビューのレイアウトファイルを指定できる

```ruby:例
class GameController < ApplicationController
  layout 'game'

  def index
    @games = Game.all
  end
end
```

このように指定すると、`GameController`のindexアクションが呼ばれたときに表示されるレイアウトは`game.html.erb`となり、なにも指定しないとレイアウトファイルは`application.html.erb`となる

###[ `<%= yield %>` ]
外部のHTMLファイルを読み込むためのerb記法

###[groupメソッド]
テーブルのレコードを指定したカラムでまとめることができるメソッド

```ruby:例
モデル.group(カラム名)
```

###[countメソッド]
groupメソッドに続けて使うとまとめられたそれぞれのレコードの数が取得できる

```ruby:terminal
Review.group(:game_id).count
=> {21=>2, 22=>1, 23=>4}
```
`game_id`が21のレコードが2つ、`game_id`が22のレコードが1つ、`game_id`が23のレコードが4つということ

ソートには`orderメソッド`を使う
理由は、`モデル.group(カラム名).count`は先ほど見たようにハッシュが返ってくるので`countメソッド`より前に`orderメソッド`を使う

```ruby:terminal
Review.group(:game_id).order('count_game_id DESC').count(:game_id)
=> {23=>4, 21=>2, 22=>1}
```

###[order('count_カラム名').count(カラム名)]
countメソッドの引数にカラム名を指定することができる、するとorderメソッドでcount_カラム名でのソートが可能となる。
→そのカラムを持つレコードの数でソートするという意味である
取得するのを１０にするには

```ruby:terminal
Review.group(:game_id).order('count_game_id DESC').limit(10).count(:game_id)
=> {23=>4, 21=>2, 22=>1}
```
###[keysメソッド]
ハッシュはkeysというメソッドを持っている
→ハッシュのキーだけを取り出して配列として返すメソッド

```ruby:terminai
Review.group(:game_id).order('count_game_id DESC').limit(10).count(:game_id).keys
=> [23, 21, 22]
```

これで、`game_id`の配列を投稿数が多い順に取得できる

###[mapメソッド]
配列オブジェクトのインスタンスメソッド
→配列の中身を１つずつ取り出してブロックという構文を繰り返し実行する

```ruby:
配列オブジェクト.map {|ele| ブロックの処理}
  # eleには配列の要素が１つずつ代入される
  # ブロックの処理は配列の要素の数だけ繰り返し実行される
```

```ruby:例
  numbers = [3, 3, 10]
  squares = numbers.map {|number| number * number}
  p squares
  => [9, 36, 100]
```

配列`numbers`の各値が二乗された数値が配列`squares`に代入される

Appsテーブルからレコードを取得するのは以下のような方法になる

```ruby:terminal
  ids = [3, 1, 2] # Appsテーブルのidの配列
  apps = ids.map {|app_id| Appsテーブルからidがapp_idのレコードを取得する}
```

###[after_sign_out_path_forメソッド]
`devise`でサインアウトしたあとのリダイレクト先を指定するメソッド
返り値にサインアウト後のリダイレクト先URLを指定し,`deiviseのメソッド`を上書きしている関係上`resource`を引数に渡さなけらばならないので、`resource`を引数に渡す

```ruby:application_controller.rb
  def after_sign_out_path_for(resource)
    '???' # サインアウト後のリダイレクト先URL
  end
```

###[authenticate_user!]
deviseをインストールすると、ログイン画面とサインアップ画面を自動で用意してくれる
このメソッドは、`deviseをインストールすることで使えるメソッド`である

ユーザーがログインしているかどうかを確認し、ログインしていない場合はログインページにリダイレクトする
→`before_action`を合わせて使用するのが通常
`before_action`の`except`や``onlyオプションを組み合わせると特定のアクションを指定することもできる

###[ImageMagick]
コマンドラインから簡単に画像の保存形式の変更などが行えるツール

••gem listコマンドでインストールされているgemの一覧が見れる、その後、
User.rbの最後に、追記→`has_one_attached :avatar`を加えることで、ユーザーのレコードと画像を紐付けできる

###[devise_parameter_sanitizer]
deviseで設定されている`strong_parameters`に対してパラメーターを追加することができる

```ruby
devise_parameter_sanitizer.permit(追加したいメソッドの種類, keys: [追加したいパラメーター名])
```

指定する引数は2種類あり、1つ目が「StrongParametersを追加したい処理の種類」

| 引数の値 | 処理 |
|:--|:--|
| :sign_up | 新規登録時 |
| :sign_in | ログイン時 |
| :account_update | レコードの更新時 |

2つ目の引数には追加したいパラメーター名を渡す、複数の場合

```ruby:
 devise_parameter_sanitizer.permit(追加したいメソッドの種類, keys: [:パラメーター1, :パラメーター2,..])
```

このメソッドは、メソッドはbefore_actionに設定する
記述するのはDeviseのコントローラを継承したコントローラかもしくはApplicationControllerにする

```ruby:application_controller.rb
before_action :メソッド名
```

```ruby:application_controller.rb
  before_action :configure_permitted_parameters, if: :devise_controller?

  def configure_permitted_parameters
    # devise_parameter_sanitizerメソッドを呼び出す
  end
```

`if`というオプションを指定するのは、`before_action`を呼び出す条件を指定するもの

###[validation(検証)]
入力フォームを通じてビューからサーバー側へパラメーターが送られてきた際、正常な値か検証することができる機能

###[validates :カラム名, presence: true]
フォームの中身があるかないかを検出し、無い場合は保存を実行しない

もし、userのe-mailががないなら

```ruby:/user.rb  
class User < ApplicationRecord
    validates :email, presence: true
```

###[placeholder: '']
フォームの中に、''で囲んだ文字をフォームの値が空の時に薄く表示しておくことができる

```erb:sample.html.erb
 <%= f.text_field :nickname, placeholder: 'ニックネームを入力（必須）' %>
```

###[image_tag]
image_tagは、htmlの<img>タグを生成するヘルパーメソッド
引数に文字列で画像ファイルのパスを取る

```erb:sample.html.erb
<%= image_tag "image/sample.jpg" %> #=> <img src="image/sample.jpg">
```