iT邦幫忙

DAY 8
1

從想法到快速實作的捷徑:Rails系列 第 8

[ Day 8 ][ Dev ] 從開發Po文功能認識MVC #1 Post的model

  • 分享至 

  • xImage
  •  

終於到了這一刻,

這一章開始就要見識到Rails有多Powerful,

我們先前說過Rails是一個框架,如果是處理基本的CRUD,

循著這個框架去做的速度簡直是比一塊小蛋糕還輕鬆。

我並不打算一次就把MVC給介紹完,畢竟從來沒接觸過的看完之後只會有種見樹不見林的錯覺。

所以老實說不太能接受幾乎每本書都這樣編排XD

不如我們直接各個擊破最後再一次彙整吧!

個人相當喜歡令狐沖最後將各家內力混合在一起後神功大成之感,

什麼?吸星大法是邪教武功,非也非也他最後還是學會了易筋經(誤

MVC: Model, View, Controller

這裡我們只focus在model上,其他兩個先不要管。

首先我們必須接觸到的是Model,Model是我們跟資料庫互動的媒介,

所有跟資料庫有關的邏輯處理都放在這裡(暫時是這樣,以後再討論有哪個更好的位置可以放邏輯相關的ruby code)

接著就直接打開terminal,在project的資料夾輸入:(別急著按enter)

rails g model post

g = generate

我們其實可以在產生model的時候就順便設定這個post在資料庫屬於他的table中會有哪些columns。

table可以把它想成對應到po文的class,
而每則po文都是符合這個class被產生出來的實例,對應到資料庫裡面的一個列(row)。
這個物件有的屬性會對應到的不同column。

補充:

產生物件並不代表就在資料表裡面生成東西,

這裡rails有activerecord這個orm幫我們做好mapping這件事。

Object Relational Mapping,簡稱ORM。

想是直接想成這樣子,但實際上orm運作的情形應該是讓我們用物件導向的思維來操作資料庫,

並非產生的物件就代表生成資料庫裡的東西,

在執行save method之後orm才會幫我們對應過去,(在rails裡面就是activerecord)

讓我們能夠用物件導向的方式來操作資料庫,不用去手刻SQL。

特別感謝kevin幫忙補充這一點,太快講過去沒注意到會造成誤會,

下方回應有他舉的例子可以看,這裡就不複製貼上了。

關於orm以及activerecord更深入的資料可以參考:

http://ihower.tw/rails3/activerecord.html

http://zh.wikipedia.org/wiki/%E5%AF%B9%E8%B1%A1%E5%85%B3%E7%B3%BB%E6%98%A0%E5%B0%84

然後我們可以回頭看一下第四天的文章,我們規劃的po文會有哪些欄位是比較基本可以現在先做的:

  • 標題
  • 內容
  • 附註
  • 資料來源

標題、內容、附註、資料來源看起來比較簡單應該是可以先做的,

除了內容可能會超過string限制的255字,其他都用string。

所以輸入的變成:

rails g model post title:string content:text note:string source:string





      invoke  active_record
      create    db/migrate/20140923035422_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml

在這裡我們先點進去db/migrate/20140923035422\_create\_posts.rb這支檔案看一下:

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.text :content
      t.string :note
      t.string :source

      t.timestamps
    end
  end
end

這裡我們只要跑budle exec rake db:migrate

Activie Record就會自動幫我們新建這個table了,不用自己去操作sql。

直接執行rake db:migrate也是可以的,只是bundle exec會執行這個資料夾底下Gemfile版本的gem,
用講的可能看起來有點不懂,其實噴過一次錯就會懂了,
總之這就是個好習慣啦XD

這裡我們還沒有辦法在瀏覽器上看到我們新增的post,

那要怎麼確認table是不是真的有被新建呢?

在project資料夾底下執行rails c --sandbox

c是console的意思,如果你寫過javascript,這個應該會有點熟悉。
--sandbox加上這個選項後會進入沙盒模式,當我們離開時做的一切都會被還原,
這裡我們只是要測試一下剛剛新增的資料表有沒有用

如果想要有更好用的console,建議裝pry-rails這個gem,

他會用pry來取代原本內建的irb,pry非常的好用,

重點是......也比較好看。

方法很簡單,只要打開Gemfile加入這一段:

group :development, :test do
  gem 'pry-rails'
end

再執行bundle install就可以了,

group裡是指定在哪個環境下裝這個gem,

像這裡就是開發和測試才會用到pry-rails這個gem。

接著就讓我們讓我們直接在console跟資料庫做互動吧!

post = Post.new(title:"標題", content: "測試內容", note:"假備註", source:" sample.com")
#<Post id: nil, title: "標題", content: "測試內容", note: "假備註", source: " sample.com", created_at: nil, updated_at: nil>

這裡我們指定了變數post,他借由Post這個class新增了一列資料,

id, created_at還有updated_at是內建的欄位,他們現在還是nil代表我們還沒將資料存進去,

現在只要執行post.save

就會看到active record幫我們做了哪些事情:(現在看不懂也沒關係,我們需要的只是熟練再熟練)

   (0.7ms)  SAVEPOINT active_record_1
  SQL (4.1ms)  INSERT INTO "posts" ("content", "created_at", "note", "source", "title", "updated_at") VALUES (?, ?, ?, ?, ?, ?)  [["content", "測試內容"], ["created_at", "2014-09-23 05:43:46.016161"], ["note", "假備註"], ["source", " sample.com"], ["title", "標題"], ["updated_at", "2014-09-23 05:43:46.016161"]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
=> true

雖然前端測試真正讓使用者輸入的地方也很重要,

但大部分debug的時候,還是離不開console的,

在這裏先對model和active record有一定的理解會讓接下來的步驟不那麼寸步難行,

Rails的學習曲線說陡峭其實也還好,只是太多事情太簡單太magic,常常還沒搞清楚發生什麼事情一切就做完了XD

而方便帶來的代價就是當真的出什麼事情,永遠都是滿頭的wtf,

明天的主題則是像前一天的controller一樣給post自己的頁面和路徑,

不一樣的是這次我們要從資料庫把資料拿出來了,

有朋友跟我反應這樣寫的囉哩八嗦的,但這都是為了未來做準備,

一步步理解才不會哪一天突然被magic反噬了!

另外也是想將各個不同的單元做比較細的切割,

一天想要講太多主題是不切實際的事情,

明天見!


上一篇
[ Day 7 ][ Dev ] 從建立首頁開始認識Rails
下一篇
[ Day 9 ][ Dev ] 從開發Po文功能認識MVC #2 新增一則po文
系列文
從想法到快速實作的捷徑:Rails30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
kevin3372000
iT邦新手 3 級 ‧ 2014-10-07 12:41:30

table可以把它想成是po文的class,
而每則po文都是符合這個class被產生出來的實例,儲存在資料庫裡面會變成一列。
每一列的不同column就代表這個物件有的屬性。

這一段敘述蠻奇怪的。

ORM 是讓你使用物件導向的思維來操作資料庫的工具,而 table,column 是關聯性資料庫裡面的東西,一個資料庫由一或多個 table 組成,一個 table 裡面有一或多個 column,而一個 table 裡面也可能有一或多筆 record。

假設我們在 controller 裡面這樣寫:

@post = Post.new

實際上它是產生一個 Ruby Object 。

假設我們 call save method :

@post.save

ORM 會幫我們跟資料庫連接,執行儲存這筆資料的動作。

假設 post 這個 table 有 title, content 這兩個 column ,今天我們想要儲存一筆新資料的話會這樣寫:

@post = Post.new
@post.title = "test name"
@post.content = "hi"

但要記住的是,直到我們執行 save method 之前,這些動作實際上都只是更改 RUby Object 的值而已。

table, column 跟 class 以及 Object 的 attriubte,是無法畫上等號的。兩個完全是不一樣的東西。

ORM 只是把原本開發者需要自己手寫 SQL 的部分抽象化,讓我們直接使用物件導向程式語言操作資料庫,我們不需要管跟資料庫連接或是要怎麼用 SQL 更新、新增、刪除資料庫的內容,這些部分 ORM 都已經幫我們 hanlde 好了。

0
tinydenny
iT邦新手 4 級 ‧ 2014-10-07 13:16:51

那裏太快把概念講過去,(只寫「想成」,沒講清楚實際上並不是這樣)
沒注意到這樣會造成誤導,已經更改過敘述並補上一些資料,
不過你舉的例子比較清楚易懂,自己懂和寫出來真的是兩回事。
學習了,謝謝你!

我要留言

立即登入留言