---
# System prepended metadata

title: 20220812 Rails 無名小站實作 (Rich) 串接文章、假資料產生Faker、Tailwind
tags: [Rails, Ruby]

---

# 20220812 Rails 無名小站實作 (Rich) 串接文章、假資料產生Faker、Tailwind
###### tags: `Ruby` `Rails`
### code hint
> 左手只是輔助


## Routes 路由設定

### Namespace
> 以前會惹
```ruby=
  namespace :ns do
    resources :books
  end
```
![](https://i.imgur.com/rcrUQpI.png)

### Scope
> 相較Namespace更多彈性(客製化的Namespace)
```ruby=
scope :bb do 
 resources :books
end
```
![](https://i.imgur.com/60LmJYN.png)

books#...
這樣controller#action沒有前綴

但scope + module, 就可以指定前綴為"sp"
```ruby=
scope :bb ,module: "sp" do 
 resources :books
end
```
![](https://i.imgur.com/Oi4ngIN.png)
scope更多使用方法，請看[官方手冊](https://guides.rubyonrails.org/routing.html)

小提醒：
如果不要路徑中的`:id`，請用`resource`

路徑越來越複雜，有時候rails會猜錯，那麼就直接餵給他吧～

小提醒：
如果怕物件不存在而出現錯誤訊息，可以用&.來判斷
&. => 前面條件成立才會再判斷後面條件

https://thoughtbot.com/blog/ruby-safe-navigation
> Ruby safe navigation, especially in long chains, can be difficult to read and can hide some subtle edge cases.

XXX.new_record? :判斷物件是不是新的

XXX.persisted? :判斷是不是舊的（已經存在於資料庫）

## 就算不能編輯，我還是可以改
雖然blog識別碼建立後不能改，但是我在開發者工具還是可以藉由一些方法改掉。



要測試方法參數(params裡面的參數)會不會被改掉
改網址參數來測試

**所以我們要在清洗這一關再加一層判斷給收到使用者的那包params, 如果是編輯(action == "update")的話 handler就不給過**
```ruby=
# blog_controller.rb
def blog_params
  if action == "update"
    params.require(:blog).permit(:title, :description)
  else
    params.require(:blog).permit(:handler, :title, :description)
  end
end
```



使用者註冊On Boarding
關乎使用者體驗 通常不要一開始就要一堆資料 而是逐步逐步蒐集
例如：我們的有名小站是註冊之後 才新增部落格 而非在註冊當下

https://en.wikipedia.org/wiki/User_onboarding

[如何設計流暢的第一次體驗，讓使用者看見產品的價值](https://medium.com/as-a-product-designer/ba932933d048)


### 新增文章


### 顯示所有文章

因為user:blog是一對一; blog:articles是一對多, 所以可以藉由user建立blog跟articles之間的關聯（要直接migration建立blog跟articles的關聯也可以）

> blog.user.articles

#### 讓頁面顯示文章部分內容
[truncate](https://apidock.com/rails/String/truncate)


#### 快速長文章
rake (還記得我嗎～～)放task的地方！可以在終端機下指令執行task
例如: rails db:migrate就是rake(rails 5之後rake改成rails而已)
- rails 5之後rake改rails應該都可以執行
重點是咚～就長出來了



```shell
$rake task  or $ rake -T #找Rakefile
```

```ruby
#長出一個eat的task, 描述是aaa, 執行$ rake eat後印出“eat"
desc :aaa #描述，就算不打也可以，還是會動

task :eat do 
  puts "eat"
end
```


```ruby!
#長出一個db:eat的task, 執行$ rake db:eat後印出“eat"
namespace :db do 
  task :eat do 
    puts "eat"
  end
end
```

套件！<3 做假資料
[faker](https://github.com/faker-ruby/faker)
但是上線時用不到，所以放在dev

套件只放在測試檔中
https://bundler.io/v2.3/man/bundle-add.1.html

#### 套件版號說明

```shell=
$ gem '套件', '~> 3.1.7' #安裝大於版號且安全穩定的版本
$ gem '套件', '> 3.1.7' #安裝大於版號
$ gem '套件', '3.1.7'  #安裝等於版號
```
3.1.7=>(major主要.minor次要.patch修正/無痛更新/向下相容)

進入rails console
打 `require 'faker'`
![](https://i.imgur.com/S5h5mKE.png)
代表已經安裝過了

效果在下面：
![](https://i.imgur.com/VXwCGf7.png)


缺少把整個環境
```ruby!
NameError: uninitialized constant User
```
把rails環境引入
加入 => :environment

```ruby!
namespace :blog do
  desc "建立初始資料"
  task :init => :environment do
    # 要先用environment把rails環境載入

# init user & aticles
    #建立五筆會員資料  
    5.times {
      u = User.create(email: Faker::Internet.email, password: "123456")

      blog = u.create_blog(
        handler: Faker::Name.unique.name.downcase.gsub(" ", "_").delete("."),
        title: Faker::Lorem.sentence,
        description: Faker::Lorem.paragraphs(number: 2).join
      )
      puts "blog #{blog.handler} created"
      # 建立10篇文章
      10.times {
        article = u.articles.create(
          title: Faker::Lorem.sentence,
          content: Faker::Lorem.paragraphs(number: 5).join
        )
        puts "  title: #{article.title} created"
      }
      puts "user: #{u.email} created!"
    }
  end
end
```
如果要做出多個會員跟文章，請記得**迴圈**

每次使用獨一無二的資料 Faker::Type.<mark>unique</mark>

#### 部落格分頁

分頁套件：[kaminari](https://github.com/kaminari/kaminari)
其他分頁套件 will paginate、pagy
上線也會用到
分頁器:kaminari送的view helper
<％= paginate @articles %>

![](https://i.imgur.com/QGWdP3Z.png =400x)


分頁套件：[pagy](https://github.com/ddnexus/pagy)

:::success
選套件:
- github星星數
- 維護積極度
:::



## 處理前端套件 tailwind

:::success
參考設計樣板
- tailwindui
- visily
:::

tree shaking 最後上線時只會打包有用到的css

[Tree Shaking|iThome-今晚，我想來點 Web 前端效能優化大補帖！](https://ithelp.ithome.com.tw/articles/10274978)


devise alternative: [sorcery](https://github.com/Sorcery/sorcery)


## Tailwind
```
$ yarn add -D tailwindcss postcss autoprefixer
$ yarn tailwindcss init
```
在postcss.config.js加上require('tailwindcss')


在Javascript創立application.css並寫上
```
@import "tailwindcss/base";
@import "tailwindcss/utilities";
@import "tailwindcss/components";

```
在Javascript/packs/application.js加上
```
import "../application.css"
```
終端機執行
```
$yarn remove tailwindcss postcss autoprefixer
$yarn add -D tailwindcss@npm:@tailwindcss/postcss7-compat
```