Rails + Bootstrap我的博客搭建的完整過程(3)

Part 7 html

-首先咱們從總體的佈局文件開始,開始美化以前我發現了一個明顯的bug,就是當我點擊一片文章顯示內容時,再次點擊導航欄的「文章列表」或者「關於博主」的時候,都會出現路由錯誤,緣由是由於我在這些連接裏面寫的地址都是固定的url地址,而不是路由,因此致使每次訪問都會在當前的頁面url後加上那個url後綴,而後頁面就會由於找不到路徑掛掉,好,修改以下: 前端

1.替換'Blog'連接爲路由,由 程序員

<a class="navbar-brand" href="/">Blog</a>

改成 shell

<%= link_to 'Blog', root_path, class: 'navbar-brand' %>

2.替換'文章列表'連接爲路由,由 數據庫

<li class="active"><a href="articles">文章列表</a></li>

改成 安全

<li class="active"><%= link_to '文章列表', articles_path %></li>

3.替換'關於博主'連接爲路由,由 ruby

<li><a href="about">關於博主</a></li>
改成
<li><%= link_to '關於博主', about_path %></li>
這段須要注意的是,<a>標籤其實就是等同於link_to這個helper,可是當<a>裏面還有CSS樣式的時候,須要在最後添加一個class參數,相似class: 'navbar-brand'這樣的。

-讓咱們來美化文章列表頁面views->articles->index.html.erb,根據咱們的要求,顯示的應該是一個列表,相似於一個表格,因此咱們的主體就是一個table,但依然是佔據着col-sm-8這麼寬的區域。因此,最開始的作完以後的代碼以下: app

<div class="row">
	<div class="col-sm-8">
		<table class="table">
			<caption>文章列表</caption>
			<tbody>
				<% @articles.each do |article| %>
					<tr>
						<td><%= link_to article.title, article_path(article) %></td>
						<td><%= link_to '編輯', edit_article_path(article) %></td>
						<td><%= link_to '刪除', article_path(article), method: :delete %></td>
						<td><%= article.created_at.to_s(:db) %></td>
					</tr>
				<% end %>
			</tbody>
		</table>
	</div>
	<div class="col-sm-4">
		
	</div>
</div>

你們能夠看到,其實咱們原來的「寫博客」的連接不見了,由於我想把它放到table的右上角,可是沒找到好辦法,想了下,由於標題<caption>其實也是一行,那就是一個row,那就可使用class=col-sm-6這樣的class來控制,因此就改爲這樣了: 佈局

<caption>
				<div class="row">
					<div class="col-sm-6" align="left">文章列表</div>
					<div class="col-sm-6" align="right"><%= link_to '新博客', new_article_path %></div>
				</div>
			</caption>
好了,到此articles的index頁面初步完成了。

-開始articles部分的new頁面,我但願輸入框的大小是不能夠拖拽改變的。 測試

那麼一樣,留出右邊的1/3的空白區域,左邊爲生成文章的區域,因此這個頁面的代碼能夠改爲:

<div class="row">
	<div class="col-sm-8">
		<%= form_for @article, url: articles_path do |f| %>
			<div class="form_content">
				<%= f.label :title, "文章標題" %>
				<%= f.text_field :title, class: "form-control" %>

				<%= f.label :content, "文章內容" %>
				<%= f.text_area :content, class: "form-control", style: "resize:none;", rows: 10 %>
			</div>
			<%= f.submit "提交", class: "btn btn-primary" %>
		<% end %>
	</div>
	<div class="col-sm-4">
	</div>
</div>
輸入框和文本框的class都是"form-control",文本框默認是能夠拖拽放大縮小的,要想保持大小,設置style屬性爲"resize:none;"便可,關於文本框的高度,設定rows值比較合適

同理,edit頁面一樣是這樣。

-開始about頁面。這個頁面僅僅就是一個文字段落,相對比較容易。修改完的代碼以下:

<div class="row">
	<div class="col-sm-8">
		<p>博主主要從事的工做是iOS開發,從2011年一次偶然的機會,喜歡上Rails,今後就變成成天想着Rails可是幹着iOS的程序員。時至2015年1月9日,實在不容許這樣的狀況持續下去,並且我熱切期待本身能有一個徹底屬於本身的博客,因此就開始着這個項目的開發,僅以此記錄開發的過程,若有問題,請來信告知。qingfengorlangyue#gmail.com</p>
	</div>
	<div class="col-sm-4">
	</div>
</div>

到此,博主的前端能力有限,心目中預計的第一步驟相關的美化工做結束,接下來就去掉一些冗餘的代碼,評論功能和頁面的持續美化。

Part 8

-首先添加評論功能,因此咱們須要設計一個Comment數據模型,以及一系列關於它的CRUD,除此以外,由於評論和文章是有對應關係的,因此還須要考慮它與article之間的關係。

從產品的角度看,每一個文章都會有0~N條評論,而每條評論都只能屬於某一片文章,因此看起來文章和評論之間的關係應該是1對多的關係。目前,以博主相對不成熟的Rails和前端技術,我就暫時設計評論的字段僅包含一個content來表示用戶輸入的內容,另外由於須要與article模型的聯繫,須要一個外鍵,因此總共是2個字段。

1.建立comment數據模型

rails generate model comment name:string article_id:integer
在app->models裏面就多了一個comment.rb模型文件,而後數據模型和數據庫是對應起來的,因此會自動生成一個migrate文件,用戶建立數據庫表

2.指定與article數據模型的關係

article.rb文件中添加

has_many :comments

comment.rb文件中添加

belongs_to :article

剛發現原來我想要的comment的字段名字命錯了,應該是content字段,卻寫成了name字段,因此在migrate目錄下面相應的遷移文件中修改過來便可。接下來生成comment數據表

rake db:migrate
好了數據模型肯定了,開始爲comment添加CRUD吧。

-建立comment控制器,命令以下:

rails generate controller comments
作"CRUD"就又會設計到相應的action,也相對應的會須要template,可是comment是依賴於article的,因此它的路由不能像article那樣是一個獨立的model路由,它的全部操做都須要先查出它所屬的article是誰,而後再操做其它內容,大部分時候,一片文章的內容和它的評論是同時出現的,因此在routes.rb中有關article和comment的部分須要改一下以支持這種關係:

resources:articles

改成

resources :articles do
  resources :comments, controller: 'comments_controller'
end
-提供建立comment的界面接口

修改views->articles->show.html.erb頁面:

<div class="row">
	<div class="col-sm-8">
		<div class="article_content">
			<h3><%= @article.title %></h3>
			<p><%= @article.content %></p>
		</div>
		<hr size="1" noshade="noshade" style="#cccccc dotted;"/>
		<textarea class="form-control form_content", style="resize:none", rows="5", placeholder="評論"></textarea>
		<div align="right">
			<button class="btn btn-primary">發佈評論</button>
		</div>
	</div>
	<div class="col-sm-4">
	</div>
</div>

從這裏咱們看到了進行評論的界面接口,可是你點擊「發佈」按鈕是不會有什麼反應的,由於這個按鈕還未關聯任何事件,從這裏開始咱們須要把他看成一個獨立的部分進行操做和HTTP請求,因此

1)這裏把它改成一個form表單,而不只僅是一個textarea和button;

2)關於form表單,咱們須要注意須要提交的參數對象和字段;

因此關於評論的這部分的代碼能夠替換爲:

<%= form_for [@article, @article.comments.build] do |f| %>
			<div class="form_content">
				<%= f.text_area :content, class: "form-control", style: "resize:none", rows: "5", placeholder: "評論" %>
			</div>
			<div align="right">
				<%= f.submit "發佈評論", class: "btn btn-primary", align: "right" %>
			</div>
		<% end %>

這裏面要注意的一個地方是

[@article, @article.comments.build]
這是這個form須要提交的參數,並且會把這個消息發送到comment控制器的create方法中,但由於comment是依附於文章的,而routes中的代碼以及它們之間的has_many和belongs_to關係

resources :articles do
  # you can use the custom controller name for comment.
  # eg. resource :comments, controller: article_comment
  resources :comments
end
會讓comment的route和普通的resource不同,對比以前article的resource獲得的對應方法和route:

Article.new
Article.create
Article.create!
comment的resource對應的方法和route:

@article.comments.build
@article.comments.create
@article.comments.create!
因此,這個form須要的內容除了comment對象自己還須要它關連的article對象。

那麼相應的,咱們須要在comment控制器中加入create方法來處理comment的建立。接着面臨的問題就是建立完評論以後,界面該如何動做?一般還須要呆在當前頁面,可是若是有關聯的comment的話,則須要顯示(多是剛剛建立的)comment。因此article的show頁面還須要加入顯示comment的部分,這部分能夠相似這樣:

<% if @article.comments.any? %>
			<div class="article_content">
				<table class="table" rules="groups">
					<tbody>
						<% @article.comments.each do |comment| %>
							<tr>
								<td><%= comment.content %></td>
								<td align="right"><%= comment.created_at.to_s(:db) %></td>
							</tr>
						<% end %>
					</tbody>
				</table>
			</div>
			<hr size="1" noshade="noshade" style="#cccccc dotted;"/>
		<% end %>

在有comment的狀況下再顯示這個區域。

在開發過程當中,我調試過程當中常常須要從rails c的console中建立測試數據,也須要刪除數據,建立咱們說過了,那麼刪除的方式相似這樣:

# 刪除表中全部數據
Comment.delete_all
# 刪除一條數據
comment = Comment.last
comment.delete

好了,到這裏咱們就能夠正常的針對具體的文章發佈評論了。

Part 9

到這裏,你們能夠看到整個頁面咱們一直在作左邊的2/3部分,右邊的部分沒有作過,因此接下來咱們就來設計右邊的1/3部分的內容。

-首先更改welcome的index頁面,這個頁面須要顯示全部的評論,並且須要是倒序的,代碼以下:

<% @comments.each do |comment| %>
				<div class="article_content">
					<%= link_to comment.content, article_path(comment.article) %>
				</div>
			<% end %>

因此,咱們須要在welcome的controller中獲取到全部通過倒序排列的comment:

def index
	@articles = Article.all
	@comments = Comment.all.reverse_order
end

但我發現,除了這個頁面,我但願全部的頁面都是在最右邊顯示這個部分,因此我須要爲每一個頁面添加以下代碼!這樣將會很是的繁瑣,並且其實失眠不少的網站的頁面都是這的佈局,那他們也是這麼作的嗎?其實有一個叫作「局部視圖」的技術能夠解決這個問題,就是解決複用的問題的。好,讓咱們開始使用它吧!

-首先看welcome的index頁面,把咱們剛剛加入的那個部分的代碼粘貼到一個新的文件裏面去,這個文件是app->views->welcome->_comment.html.erb而後把index裏面的那段代碼替換成

<%= render "comment" %>
而後你能夠刷新一下看看,構建完代碼以後,是一樣的效果,好的,那我麼就把它加到每一個須要的頁面中去吧!

-在article的index頁面,去掉原來的

<div class="col-sm-4">
</div>
替換爲:
<%= render "./welcome/comment" %>

注:由於_comment.html.erb是放在welcome目錄中的,而在搜索局部視圖的時候,render後面的實際上是一個相對路徑,因此這裏咱們須要改變一下,把它的路徑換成welcome中的路徑,不然就會尋找當前目錄下的_comment.html.erb文件,而由於找不到就報錯了。

-在article的show頁面,作一樣的修改便可。

-welcome的about頁面

-article的new頁面

-article的edit頁面

作完這些你會發現你須要在幾乎每一個對應頁面的action中添加一行代碼

@comments = Comment.all.reverse_order

這也是一種代碼的冗餘,rails依然有比較好的作法可讓代碼優化,咱們可使用before_action來達到這一目的。before_action的意思是你在執行這個指令所包含的全部方法以前都須要之行另一個在這裏規定好的方法。

1.修改welcome控制器,在全部方法的最前面添加以下代碼:
before_action :all_comments, only: [:index, :about]

這意味着在index和about方法執行前,先要執行all_comment方法,這個方法的定義以下:

def all_comments
	@comments = Comment.all.reverse_order
end

其實就是獲取了全部的comments,沒什麼特別的,當沒有:only字段來限定的話,是對全部的方法都起做用的

2.一樣的修改article控制器,在最前面添加

before_action :all_comments, only: [:index, :show, :edit, :new]

好了,到這裏,這是我可以想到的全部的代碼優化部分。

Ok,又發現一處能夠去掉冗餘代碼的地方,就是article的new.html.erb 和 edit.html.erb頁面中關於form的部分。

在article的目錄中新建一個_form.html.erb,把相同的部分

<div class="form_content">
	<%= f.label :title, "文章標題" %>
	<%= f.text_field :title, class: "form-control" %>

	<%= f.label :content, "文章內容" %>
	<%= f.text_area :content, class: "form-control", style: "resize:none;", rows: 10 %>
</div>

相應的new和edit中相同的代碼能夠替換爲

<%= render partial: "form", locals: { f: f } %>

此次的複用和上次優勢不一樣,多了一個參數locals,並且前面也多了個叫partial的symbol,這是由於此次咱們須要傳遞一個參數到局部視圖中去,否則局部視圖就不知道里面的那個「f」是什麼意思了,而一旦須要傳遞參數,前面就須要添加partial這個symbol來保證參數的形式同樣。

好了,接下來的工做就是網站的安全性部分,包括防意外髒數據的插入,字段不爲空的檢測,格式要求,和最主要的測試部分。之因此把測試放在最後,並非什麼所謂的TDD和BDD,是由於咱們初學者須要成果的展現,須要成就感,僅是我的的觀點,因此我就這麼作。

相關文章
相關標籤/搜索