ruby on rails を AWS Cloud9で実施 1　railsサーバー立ち上げまで　python初心者

# python 以外も学ぶ必要性

これまで研究のため
盲目的にpython の機械学習　だけを勉強してきましたが
実際に多くの現場で使用していただけるシステムを
作る為には　様々な言語を学ぶ必要性に気付き
ruby について　勉強したので備忘録として残します

環境　AWS Cloud9
environment type EC2
instance type t2.micro
platform ubuntu server 18.04 LTS

# まずはruby について

https://techacademy.jp/magazine/22202

## to_sメソッド

python では　str() などでですが
ruby では　to_s メソッドとなります

to_sメソッドとは
to_sメソッドとは、文字列以外のオブジェクトを文字列に変換するメソッドです。例えば、数字を文字列に変換したり、小数を変換するのに使用します。

Rubyでは数字と文字列をそのまま+演算子でくっつけることができないので、数字と文字列をくっつけて表示したい時などに利用します。

to_sの書き方
to_sメソッドは、以下のように使用します。
```
オブジェクト.to_s
```

例えば数字を変換する場合は
```
10.to_s # => "10"
```
といった形で使用します。

## メソッド

ruby のメソッドは　
python では関数と大体同じなのですが
rubyではオブジェクトに属していることから
メソッドと呼ばれています

ruby　の　to_s　を利用して　メソッドを作成してみましょう

以下のコマンドをターミナルで実行し
ファイル作成
```
touch fizz_buzz.rb
```

```fizz_buzz.rb
def fizz_buzz(n)
  #n を　15 で割ると余りが０の値だった場合　Fizz Buzz
  if n % 15 == 0
    'Fizz Buzz'
  #n を　3 で割ると余りが０の値だった場合　Fizz
  elsif n % 3 == 0
    'Fizz'
  #n を　5 で割ると余りが０の値だった場合　Fizz
  elsif n % 5 == 0
    'Buzz'
  #ここでto_s　を利用する　n　を文字列に変換する
  else
    n.to_s
  end
end

puts fizz_buzz(15)
puts fizz_buzz(1)
puts fizz_buzz(5)
```

上記のように一部で　to_s　を利用することで
メソッドに入力した値をそのまま　文字列に変換して　
出力することが可能です


## 配列 と　メソッド
配列 は 複数 の データ を まとめて 格納 きる オブジェクト のことです 
配列内 の データ 要素 は 、 順番 に 並んでいて
添字 インデックス を 指定 する ことで データ を取り出せ ます


https://qiita.com/kenbu/items/6ceae8fb970ad4b17b53

https://note.nkmk.me/python-list-initialize/

上記の記事でもわかるのですが
python と　ruby の配列の定義は非常に似ています

```
# 良い例
arr = []
```

ruby で配列を作成してみます 

to_a メソッド と　require関数　を利用します

#### to_a メソッド
to_aメソッドとは、レシーバー自身を返すメソッドです
Arrayのサブクラス（Arrayクラスを継承しているクラス）
に対して使用する場合は、配列に変換されたものを返します

よく範囲オブジェクトを、配列に変換する際に使用します

https://techacademy.jp/magazine/22203



```fizz_buzz_to_a.rb
#require './ruby_projects/fizz_buzz'

# 0から25までの値を持つ　配列を作成
l = (0..25).to_a

#  fizz_buzzメソッドを作成
def fizz_buzz(n)
  #n を　15 で割ると余りが０の値だった場合　Fizz Buzz
  if n % 15 == 0
    'Fizz Buzz'
  #n を　3 で割ると余りが０の値だった場合　Fizz
  elsif n % 3 == 0
    'Fizz'
  #n を　5 で割ると余りが０の値だった場合　Fizz
  elsif n % 5 == 0
    'Buzz'
  else
    n.to_s
  end
end

# fizz_buzzメソッドを呼び出す
fizz_buzz(l)

```

https://qiita.com/yohm/items/18b1f206267c31f4da72



## クラスの利用

クラスとは、インスタンスを作成する時の「元となる設計図のこと」です
Rubyは、「もの」を組み立てる様に表現してコンピュータに指示する
オブジェクト指向プログラミング言語です
「もの」を組み立てる際の設計図を「クラス」と呼び、
その「設計図から作成された実物体」のことを「インスタンス」と呼びます

#### initialize
インスタンスメソッドの中で「initialize」と
言う名前が付けられたメソッドは
特殊なメソッドです

このメソッドをクラス内に記述した場合には
オブジェクトが作成される時に自動的に呼び出されます

```

class クラス名

  def initialize()
    処理
  end

end
```

python の init に近い考え？

https://www.fenet.jp/dotnet/column/language/7263/


#### classをnewで作成する方法
classの定義はしましたが、そのままではclassをコード中で使用できません。

classのnewメソッドによって、classをインスタンス化する必要があります。

インスタンス化とは、classの定義をもとに新たな変数を作成することです。

具体的な例を見てみましょう

```
class Hello
 
  # クラスの初期化メソッド
  def initialize
 
  end
  
  # クラスのインスタンスメソッド
  def talk
    puts "hello, world"
  end
  
end

# newメソッドによるclassの初期化
hello = Hello.new
 
# Helloクラスのtalkメソッドを実行
hello.talk
```

実行結果：
```
hello, world
```

上のコードでは、Hello.newメソッドを使って、
Helloクラスをインスタンス化、つまり変数化しています

その後、変数helloに対して
talkメソッドを実行するよう命令しています

その結果、Helloクラスの
talkメソッドが実行され、「hello, world」が出力されています

このように、classは定義したままでは使用できず、
newメソッドによりインスタンス化して初めて、classのメソッドが使用できるようになります

https://www.sejuku.net/blog/21170

### クラスを作成してみる
```
touch car.rb
```

```car.rb
#car クラス作成

class Car
  def initialize(name)
    @name = name
  end
  
  def hello
    puts "hello I am #{@name}.I'll say it again.I am #{@name}"
  end
end

#ceml の 自動車のインスタンスを登録
car = Car.new('ceml_car')
car.hello

#アニキの自動車のインスタンスも登録
brother_car = Car.new('Big brother car')
brother_car.hello
```
実行すると
```
"hello I am #{@name}.I'll say it again.I am #{@name}"
```
の部分が
'ceml_car'
'Big brother car'
で表示されます

```
hello I am ceml_car.I'll say it again.I am ceml_car
hello I am Big brother car.I'll say it again.I am Big brother car
```
上記のように　何度も　自分の車名をいうことが可能です

## アクセサメソッド

アクセサメソッドとは
インスタンス変数の値を読み書きするメソッドです

```
 touch accessor.rb 
```

```accessor.rb
#car クラス作成

class Car
  def initialize(name)
    @name = name
  end
  
  def hello
    puts "hello I am #{@name}.I'll say it again.I am #{@name}"
  end
  
  def name
    @name
  end
  
  def name=(value)
    @name = value
  end
  
  
end

#ceml の 自動車のインスタンスを登録
car = Car.new('ceml_car')
car.hello
#①
#①puts car.name

#①以下のようなコマンドでクラスの外部から直接インスタンス変数は参照できない
#car.@name

#①そこで以下のように　メソッドを定義する
#  def name
#    @name
#  end
puts 'before'

puts car.name


#②　インスタンス変数@neme はクラスの外部から書き込むことができない
# そこで　メソッドを呼び出すように　外部から書き換える方法を利用する
# インスタンスメソッド　という
# def name=(value)
#  @name = value
# end
# 以下のコマンドでceml_car　が　special brother　（スペシャルアニキ）に変化する

car.name = 'special brother'

puts 'after'

puts car.name


#アニキの自動車のインスタンスも登録
brother_car = Car.new('Big brother car')
brother_car.hello

```
実行結果

```
hello I am ceml_car.I'll say it again.I am ceml_car
before
ceml_car
after
special brother
hello I am Big brother car.I'll say it again.I am Big brother car
```

https://qiita.com/yoshimitsu_g/items/5f174ff74d8e8b15b0be

## クラスメソッドと定数

クラスメソッド
はクラスから直接読むことができるメソッド

定数名は全て大文字となります
REGION = 'japan'　の部分です

```
 touch class_val.rb 
```

```class_val.rb 
#car クラス作成

class Car
  REGION = 'japan'
  @@count = 0
  def initialize(name)
    @name = name
    @@count += 1
  end
  
  def hello
    puts "hello I am #{@name}.I'll say it again.I am #{@name}__#{@@count}var"
  end
  
  def name
    @name
  end
  
  def name=(value)
    @name = value
  end

  def self.info
    puts "#{@@count} instance Region: #{REGION}"
  end
  
end

#定数をクラスの外から参照したい場合は
puts Car::REGION

car = Car.new('ceml_car')
Car.info
car.hello

car2 = Car.new('ceml_car2')
Car.info
car2.hello

car3 = Car.new('ceml_car3')
Car.info
car3.hello


#インスタンス変数が実行されるたびに　initialize　メソッドが呼ばれ
#@@count がインクリメントされて　インスタンスの生成数が増えていく

```

## クラスの継承
親クラス　スーパークラス　の機能を引き継いで
子クラス　サブクラス　を作成することができる

コードの再利用性や拡張性を高める仕組み

```
 touch sub_class.rb 
```

```sub_class.rb 

#親クラス
class User
  def initialize(name)
    @name = name
  end
  
  def hello
   puts "Hello I am #{@name}."
  end
end

#子クラス　　　AdminUser クラスを継承
class AdminUser < User
  def admin_hello
    puts "Hello I am #{@name} from AdminUser"
  end
  
  def hello
   puts "Hello I am AdminUser #{@name}."
  end
  
end



#親クラス
oya = User.new('oya')
oya.hello


#子クラス
chi = AdminUser.new('chi')
chi.hello

chi.admin_hello

#親クラスのメソッドを使ってみる　オーバーライド　という
#子クラスを利用することで　親クラスを変更することなく
#子クラスを編集できる
```
こちらも参考になります

https://www.javadrive.jp/ruby/inherit/index1.html


## モジュール

クラスのようにメソッドや定数をまとめられるもの

モジュールの用途
関連するメソッドや定数　をまとめて
グループ化するときに便利

```
 touch module.rb 
```
```
module Driver
  def self.run
    puts 'Run'
  end
end

Driver.run
#Driver.stop
```
## 例外処理
https://qiita.com/k-penguin-sato/items/1a6c8096effccb19565a


## メソッドの公開範囲


## require関数
require関数は、標準ライブラリやインストールした
ライブラリから使用する場合には
ライブラリ名を渡すことで使えます

# Ruby on Rails
ここからはRuby on Railsについての説明となります 

動作環境
Ruby 3.0.2
Ruby on Rails 7.0.0

google chrome 最新の安定バージョン


コンソールでrubyの確認
```
ruby -v
```
出力は　ruby 3.0.2p107


現在有効になっている　railsの確認
```
 rails -v
```

念のため
gem が使えるか確認します
gem とは

### Ruby Gems(gem)
Ruby で書かれたサードパーティー製のライブラリ
プログラムのまとまり
https://techplay.jp/column/529


```
gem -v
```
出力　3.2.22

最新のバージョンのrailsをインストールする場合
```
gem install rails
```
バージョンを指定してインストール
```
gem install rails -v 7.0.0 -N
```
再度有効になっている　railsの確認
```
 rails -v
```
出力　

Rails 7.0.0

となるはずです


## rails の　基本理念

#### 設定より規約

convention over configuration coc

データベースのテーブル名はモデルの複数形にする

モデル名　User ⇒　データベースのテーブル名:users

#### 同じことを繰り返さない

Don’t Repeat Yourself:：DRY

同じことを繰り返さない」というのは
同じ意味や機能を持つ情報が複数の場所に置かれていると
変更時に整合性がとれなくなる危険性が高まるため
なるべく避けるべきとする考え方です


## MVC アーキテクチャ

#### model
データベースアクセスなど　データ関連処理

#### View
画面表示

#### controller
リクエストやレスポンスを制御
view と model の橋渡し

以下はMVCの相関図ですが　ひどい図です
人によってMVCの解釈は異なるみたいですので
ざっくりとした図で解釈していただけると幸いです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/98c0f860-9748-063b-4e3e-80b29ca85ee2.png)


## 新規railsプロジェクトの作成

#### 作業用フォルダ作成

~/enviroment
で以下のコマンド入力

```
mkdir rails_projects/

cd rails_projects/
```
上記のコマンドで　rails_projects　フォルダ作成後

rails_projects　に移動します

#### 新規railsプロジェクト を　バージョン指定して作成

例えば　hello という新規プロジェクトを作成する場合は
以下のコマンドです

```
rails new hello
```

今回はバージョンを指定して立ち上げたいので

```
rails _7.0.0_ new hello
```
となります

上記コマンドで　hello フォルダが作成されました

```
ls

cd hello

ls -la
```
上記コマンドで　hello フォルダの確認もできます
これで　rails プロジェクトのひな型ができました

AWS Cloud9
左側の　ファイルエクスプローラでも確認可能です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/5c7530e1-1e22-e0bf-77ea-ed923513e036.png)


## railsサーバー立ち上げてみる

railsサーバー立ち上げるコマンド

```
rails s
```
rails 7 では　セキュリティ上から
ホワイトリストに登録されてないリストだとブロックされます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/dec35c91-6131-cc6a-5fc1-f1571d25e40e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/e5b8ce6c-3bfe-4f59-9a65-becfd65695cd.png)

ホワイトリストを一時的にクリア　＊学習用の方法です
```
config.hosts.clear
```

再度
railsサーバー立ち上げるコマンド
```
rails s
```

この状態でサーバー経由
サーバーのURLは各自異なる
確認のためには↓のプレビューウインドウを開き　

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/1694c701-8777-a106-8c83-78e5c34a88eb.png)

ポップアウト　ボタンをクリックで確認　となります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/f729cd72-eda2-d612-490a-7021b914018e.png)



ここで表示されているURLが各自に割り当てられているものです！

ここまでで　新規rails プロジェクトの作成と　動作が確認できました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629668/eb79a5f2-0b11-3bf2-d111-7bb3c771686e.png)

reils サーバー終了は　ctrl + C

次回は　rails の　コントローラー や View について記載します

https://qiita.com/TaichiEndoh/items/9c19319df04a279403a3


# 参考URL
https://rubyinstaller.org/downloads/

https://qiita.com/OKIDOKI000/items/25c37dd354aa471f5690

https://qiita.com/za_spa/items/6ca0d01e1156264742ab

https://udon.little-pear.net/msys2-pacman-pgp-update/

https://www.msys2.org/

https://teratail.com/questions/338070?sort=3

https://sappolog.hatenablog.com/entry/programming/ruby/devkit-install


https://qiita.com/maangie/items/51348ec584dd3e750f99