Rails 之旅第 2 天:Rails 關(guān)聯(lián)和拖動 div
大家好!今天是我搭建這個玩具項目的第 2 天。下面再來記錄一下關(guān)于 Rails 的一些有趣的事情吧!
目標(biāo):做一個冰箱詩歌論壇
我想做一種無聊的標(biāo)準(zhǔn)網(wǎng)站來學(xué)習(xí) Rails,并且其他人可以與之互動,就像一個論壇一樣! 但如果人們真的可以在網(wǎng)站上打字,那就會產(chǎn)生各種各樣的問題(如果他們是垃圾郵件發(fā)送者怎么辦?又或者只是言語刻薄?)。
我想到的第一個想法是,可以讓人們與網(wǎng)站互動,但實際上卻不能在網(wǎng)站上打字,那就是一個“冰箱詩歌論壇”,只給你一組固定的字,你就可以隨意組合。
所以,這就是我們的計劃!
我這個項目的目標(biāo)是想知道我是否能用 Rails 來做其他的小型網(wǎng)絡(luò)項目(而不是像我通常做的那樣,使用一些更基本的東西,比如 Flask,或者放棄后端,用 Javascript 來寫所有東西)。
怎么把字拖來拖去呢?jQuery 的可拖放 UI!
我想讓大家能夠把文字拖動起來,但我又不想寫很多 Javascript。結(jié)果發(fā)現(xiàn)這超級簡單 —— 有一個 jQuery 庫可以做到,它叫做 draggable!一開始,拖動并不成功。
一開始拖動在手機上是不行的,但是有一個技巧可以讓 jQuery UI 在手機上工作,叫做 jQuery UI touch punch。下面是它的樣子(有興趣看工作原理的可以查看源碼,代碼很少)。
bananaforestcakeis
一個有趣的 Rails 功能:關(guān)聯(lián)
我以前從來沒有使用過關(guān)系型 ORM,對于 Rails,我很興奮的一件事就是想看看使用 Active Record 是什么樣子的!今天我了解了 Rails 的 ORM 功能之一:關(guān)聯(lián)。如果你像我一樣對 ORM 完全不了解的話,那就來看看是怎么回事吧。
在我的論壇中,我有:
- 用戶
- 話題(我本來想把它叫做“線索”,但顯然這在 Rails 中是一個保留詞,所以現(xiàn)在叫做“話題”)。
- 帖子
當(dāng)顯示一個帖子時,我需要顯示創(chuàng)建該帖子的用戶的用戶名。所以我想我可能需要寫一些代碼來加載帖子,并為每個帖子加載用戶,就像這樣(在 Rails 中,Post.where 和 User.find 將會運行 SQL 語句,并將結(jié)果轉(zhuǎn)化為 Ruby 對象):
@posts = Post.where(topic_id: id)@posts.each do |post|user = User.find(post.user_id)post.user = userend
這還不夠好,它要為每個帖子做一次單獨的 SQL 查詢!我知道有一個更好的方法,我發(fā)現(xiàn)它叫做關(guān)聯(lián)。這個鏈接是來自 https://guides.rubyonrails.org 的指南,到目前為止,它對我很有幫助。
基本上我需要做的就是:
- 在
User模型中添加一行has_many :post。 - 在
Post模型中添加一行belongs_to :user。 - Rails 現(xiàn)在知道如何將這兩個表連接起來,盡管我沒有告訴它要連接到什么列上!我認(rèn)為這是因為我按照它所期望的慣例命名了
posts表中的user_id列。 - 對
User和Topic做完全相同的事情(一個主題也有很多帖子:has_many :posts)。
然后我加載每一個帖子和它的關(guān)聯(lián)用戶的代碼就變成了只有一行! 就是這一行:
@posts = @topic.posts.order(created_at: :asc).preload(:user)
比起只有一行更重要的是,它不是單獨做一個查詢來獲取每個帖子的用戶,而是在 1 個查詢中獲取所有用戶。顯然,在 Rails 中,有一堆不同的方法來做類似的事情(預(yù)加載、急切加載、聯(lián)接和包含?),我還不知道這些都是什么,但也許我以后會知道的。
一個有趣的 Rails 功能:腳手架!
Rails 有一個叫 rails 的命令行工具,它可以生成很多代碼。例如,我想添加一個 Topic 模型/控制器。我不用去想在哪里添加所有的代碼,可以直接運行
rails generate scaffold Topic title:text
并生成了一堆代碼,這樣我已經(jīng)有了基本的端點來創(chuàng)建/編輯/刪除主題(Topic)。例如,這是我的現(xiàn)在的主題控制器,其中大部分我沒有寫(我只寫了高亮的 3 行)。我可能會刪除很多內(nèi)容,但是有一個起點,讓我可以擴展我想要的部分,刪除我不想要的部分,感覺還不錯。
數(shù)據(jù)庫遷移!
rails 工具還可以生成數(shù)據(jù)庫遷移! 例如,我決定要刪除帖子中的 title 字段。
下面是我要做的:
rails generate migration RemoveTitleFromPosts title:stringrails db:migrate
就是這樣 —— 只要運行幾個命令行咒語就可以了! 我運行了幾個這樣的遷移,因為我改變了對我的數(shù)據(jù)庫模式的設(shè)想。它是相當(dāng)直接的,到目前為止 —— 感覺很神奇。
當(dāng)我試圖在一列中的某些字段為空的地方添加一個“不為空”(not null)約束時,情況就變得有點有趣了 —— 遷移失敗。但我可以修復(fù)違例的記錄,并輕松地重新運行遷移。
今天就到這里吧!
明天,如果我有更多的進展,也許我會把它放在互聯(lián)網(wǎng)上。

















