---
# System prepended metadata

title: Ruby on Rails - 2023/11/16
tags: [Ruby]

---

# Ruby on Rails - 2023/11/16

## 什麼是伺服器？

> 伺服器（英語：server）指：一個管理資源並為使用者提供服務的電腦軟體，通常分為檔案伺服器（能使使用者在其他電腦存取檔案），資料庫伺服器和應用程式伺服器。執行以上軟體的電腦，或稱為網路主機（host）。——Wiki

> Server 本質上是無窮迴圈，一直在等指令進來

### 可以用伺服器做什麼事？

把多個檔案（.php, .rb...等）放在伺服器裡，再變成 HTML,CSS，丟回 HTML 給使用者看

### 伺服器軟體

要設定好模組(例如：Ruby 的 rake)，才能夠避免直接傳給使用者原始碼（例如：php,rb）常見的伺服器軟體：

- Apache
- Nginx

#### 小試身手 1:使用 JS 開伺服器

```javascript
var http = require("http");

//create a server object:
http
  .createServer(function (req, res) {
    res.write("Hello World!"); //write a response to the client
    res.end(); //end the response
  })
  .listen(8080); //the server object listens on port 8080
```

使用終端機執行此檔案，開啟：http://localhost:8080/ 可以看到 Hello World!

#### 小試身手 2:使用 ruby 開伺服器

- 建立一個 rb 檔案，裡面寫入：

```ruby
rackup
```

- 再建立一個`config.ru`檔案，在此檔案內寫入

```ruby
run do |env|
  [200, {}, ["Hello World"]]
end
```

- 在終端機輸入`$ rackup`
- 架設伺服器成功，點進 http://127.0.0.1:9292 可以看到 Hello World!

#### 補充

- rack requset 一定會回傳

```ruby
# int(status)
# hash(header, content-type)
# array
```

```ruby
run do |env|
  [200, {}, ["Hello World"]]
end
```

- 上面這段程式碼，`Hello World` 的位置最重要，網頁的內容會寫在這

## CRUD = Create, Read, Update, Delete

### 目前可以做什麼專案

- V 電商
- V 訂房
- V 課程平台
- ? ubereats（主要研究 GPS 得比較多）
- X Netflix - 影音串流（太複雜）
- 聊天 discord - 使用 websocket / actioncable(Rails)
  - 可以當附加功能
- ? 交易,看盤（資料來源不易）

## 開始做專案

- 電商網站，名字 InkMelody
- Rails 7 開始使用 importmap -> 只能處理 JS,css 不太好用
- 解決辦法：用 tailwind 處理畫面（inline css）

### 建立一個新專案

進入目標資料夾後，在終端機輸入

```ruby
$ rails new InkMelody -j esbuild -c tailwind
```

#### 補充：安裝套件

- 更新 Gemfile + bundle install，使用`$ bundle add <套件名稱>`
- 僅使用 `$ gem install`，要寫套件名稱，僅下載。
- 僅使用`$ bundle install`，會秀找不到 gemfile。
  - 根據 gemfile 去做 gem install，避免各版本衝突

---

- Gem 說明：
- `$ gem "bcrypt", "~> 3.1.7"` 幫抓最新版本的 patch 版號
- `$ gem "bcrypt", "> 3.1.7"` 安裝比此版本新的
- `$ gem "bcrypt", "3.1.7"` 安裝此版本前的

---

#### 補充：版號說明

`3.1.7` 版號說明

|   3   |   1   |   7   |
| :---: | :---: | :---: |
| major | minor | patch |

- RC = Release

---

## Rails

此區塊會包含錯誤狀況處理，若要看整理版，請直接跳至快速步驟整理：https://hackmd.io/mNGSTGN8QGKL9iwyTNaKng?view#%E6%AD%A5%E9%A9%9F%E6%95%B4%E7%90%86

### **Route**
- 可以想像成整個網站的門口阿婆
- 代表這個網站總共有哪些路徑可以走，如果沒有回應 404
- 檔案放在：`cmd`+`p`快速搜尋`routes.rb`
- 在 `routes.rb` 內寫看看

```ruby
    get "/about", to: 'pages#about'
```

- 此時開啟伺服器，在瀏覽器網址列輸入`http://127.0.0.1:3000/<亂打一通>`，會出現 `**Routing Error No route matches [GET] "/aboute"**`

![01](https://hackmd.io/_uploads/rkI_3H7NT.png)


- 在瀏覽器網址列輸入`http://127.0.0.1:3000/about`，會出現`Routing Error uninitialized constant PagesController `

![02](https://hackmd.io/_uploads/HJeYhSXEp.png)


- `$ rails g controller pages`
- 會出現 `app/controllers/pages_controller.rb`
- 此時再開啟瀏覽器輸入`http://127.0.0.1:3000/about`

![03](https://hackmd.io/_uploads/B1PK3SQNT.png)

- 至`pages_controller.rb`，輸入

```ruby
class PagesController < ApplicationController

def about
end

end
```

![04](https://hackmd.io/_uploads/HJ2Fnr74a.png)


- 再回`pages_controller.rb`

```ruby
def about
  render(html:'hihihi')
end
```

- 此時畫面變成

![05](https://hackmd.io/_uploads/HyZq2S7Vp.png)


- 在 views->pages 新增檔名`about.html.erb`
- `pages_controller.rb` 改成

```ruby
def about
end
```

- 因為 about 檔名相同，所以`pages_controller.rb`內的
```def about```內不用寫

### 步驟整理

![06](https://hackmd.io/_uploads/rJv52B7Ea.png)


- **`Terminal`**
```
$ rails new InkMelody -j esbuild -c tailwind

or

$ rails new InkMelody -j bun -c tailwind
```

```
$ cd InkMelody
$ rails g controller pages
```

- **`routes.rb`**
```ruby
    get "/about", to: 'pages#about'
```

- **`pages_controller.rb`**
```ruby
class PagesController < ApplicationController

def about
end

end
```

- 在 /views/pages 新增檔案 **`about.html.erb`**
- **`about.html.erb`**
```html
可以在此寫html
```

---

### 副檔名 erb

erb = embedded ruby，可以在裡面塞 Ruby code

- `about.html.erb`

```ruby
<h1>關於我們</h1>
<%= (1..42).to_a.sample(5) %>
```

- `Ruby`在`erb`的格式：`<%= (ruby語法) %>`，`=`意思為把東西放在畫面上
- 使用 html 的註解`<!-- -->`，還是會運算，只是不會出現在畫面上，要註解請用`<%#%>` or 刪掉
- 盡量不要在 view 內寫複雜的程式，讓他僅負責視覺就好
- 若要寫程式碼可以寫在`pages_controller.rb`，變數名稱以`@變數名稱`命名，再將`@變數名稱`引入即可

### @實體變數

之後說明

## Ruby

### 可以省略小括號

以下 function 可運行

```ruby
def age
end
puts age
```

### Ruby 沒特別寫，最後一行結果是回傳值

### 印出東西

```ruby
print
puts
p
```

僅有p 有回傳值

### hash

ruby 稱為 hash JS；稱為 object；python 稱為 dictionary

```ruby
hero = {
  name:'cc',
  age:18
}

p hero
```

上面這種寫法會拿不到東西，因為上面的寫法是語法糖，原始的 hash 寫法應該是：

```ruby
{:name => "cc",:age => 18}
```

所以要寫成

```ruby
hero = {
  name:'cc',
  age:18
}

p hero[:name]
```
結果："cc"