--- title: 12th 鐵人賽 Day_13 一對多? & 部落格文章系統 tags: 12th 鐵人賽 --- # 12th 鐵人賽 Day_13 model 一對多? & 部落格文章系統 嗨!各位朋友大家好,打給後,歹嘎吼,胎尬喉,我是阿圓,一樣有請今天的one piece: ( model 關聯性就像海軍的階級啊!) # model 一對多? 部落格接下來要進展到文章的階段了,在此之前,先來講一下 model 關聯性吧。 ## 關聯性? 什麼是關聯性, Rails 將model用分層級的方式來連接 model (可以用上司下屬的感覺去聯想),也就是透過宣告的方式,讓 a model 屬於 b model ,而這樣的方法可以讓在建立資料的時候簡單很多,因為 Rails 會幫你做出好用的方法,以官方文件的例子來說: 若不設立關聯性,在建立一筆屬於顧客的訂單時,必須在建立的時候在指定一個顧客id給他: ```ruby @order = Order.create(order_date: Time.now, customer_id: @customer.id) ``` 若要刪除顧客及他所有的訂單又更麻煩了,要先將訂單都撈出來,一筆一筆刪掉後,再刪顧客: ```ruby @orders = Order.where(customer_id: @customer.id) @orders.each do |order| order.destroy end @customer.destroy ``` 使用關聯性: ```ruby= class Customer < ActiveRecord::Base has_many :orders, dependent: :destroy end class Order < ActiveRecord::Base belongs_to :customer end ``` 建立訂單: ```ruby @order = @customer.orders.create(order_date: Time.now) ``` 刪除顧客及他所有的訂單: ```ruby @customer.destroy ``` 而 model 之間彼此的關聯性主要有三種: 1. 一對一 2. 一對多 3. 多對多 我主要會著重在一對多跟多對多。 ## 一對多關聯性 ### has_many 用部落格的方式去想,一個admin會有很多的articles ```ruby class Admin < ActiveRecord::Base has_many :articles #盡量是複數喔! end ``` 這樣的話,rails 對於 admin,會生出一些方法可以用: ```ruby= admin1 = Admin.first articles1 = Articles.first #===========# admin1.articles # 可以列出admin1的所有文章,是一個陣列 admin1.articles = articles1 #把 articles1 這篇文章指定給admin1 #請注意,這樣是把admin1的所有文章砍掉只剩articles1喔,若是要新增,請使用 admin1.articles << articles1 admin1.articles.build(title:'一對多關聯性') #用admin1的角度,建立一篇標題為'一對多關聯性的'文章 #要再呼叫save方法才會存入資料庫 admin1.articles.create(title:'一對多關聯性') #同上,不過不需呼叫save方法 ``` ### belongs_to 而這些articles會屬於admin。 ```ruby= class Article < ActiveRecord::Base belongs_to :admin #盡量是單數喔! end ``` 一樣,對於 article,會生出一些方法可以用於反查: ```ruby= admin2 = Admin.second articles2 = Articles.second #===========# articles2.admin # 列出 articles2 的作者 articles2.admin = admin2 #把articles2的作者,指定為admin2 ``` ### 迷思 1. 我在資料的欄位裡面有一個admin_id的欄位就有關聯了嗎? 沒有!資料表是資料表,你只是開了一個欄位給他用,而這個欄位會寫上一個數字,剛好是admin的id,但不代表有關聯性,請去 model 指定關聯性給他們。 3. 設定has_many後,一定要有belongs_to嗎? 不用!如果不需要做到反查的動作,就不需要設定belongs_to 接著讓我們進行部落格實作的部分! # 部落格實作 ## debug 昨天發現一個bug,我current_admin的方法寫錯了,囧" 請聽我娓娓道來: admin 登入後會有一個發一個`session[:admin_token]`給他,但我沒有讓它存在任何一個欄位裡,根本就找不到這個admin啊! 所以我對admin的資料表多開一個欄位放token,並將sign_in跟current_admin的部份改寫了一下: ```ruby= # admin_controller private def sign_in_admin(admin) session[:admin_token] = SecureRandom.uuid admin.update(token: session[:admin_token]) end ``` ```ruby= # application_controller def current_admin @current_admin ||= Admin.find_by(token: session[:admin_token]) end ``` 其實也可以使用環境變數寫死,不過這樣在之後上線的時候會需要設定比較多東西~所以我選擇開一個欄位~ ### articles 接著我們進行到文章的部分,有些重複的動作我一樣寫概略,這部分會著重在model那邊。 1. 先去routes.rb,指定一下articles的路徑 2. 建立articles_controller 3. 建立7個action 4. 開始建立model 一樣先來想一下我們的資料裡們會需要有哪些欄位? 1. 標題:string 2. 內文:string 3. admin_id:integer 其中 admin_id 就是為了最上面所說的一對多關聯性,而建立model的時候,可以用`rails g model Article title content admin:references` 用`:references`的話,會自動去model幫你加上`belongs_to :admin`,降低寫錯的機率! 好的,明天我們再來繼續多對多關聯性以及文章分類的部分,感謝各位看到這邊,若有任何建議,請各位不吝指教!我們明天見!  [部落格GitHub](https://github.com/gn2481/yuan_blog) #### 參考文章 [為你自己學 Ruby on Rails](https://railsbook.tw/chapters/18-model-relationship.html) [官方文件](https://guides.rubyonrails.org/association_basics.html)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up