在使用Rails之前,讓我們回顧一下Ruby的幾個要點,它是Rails的基礎。
Ruby是成功的−
- Smalltalk's conceptual elegance,
- Python's ease of use and learning, and
- Perl's pragmatism.
魯比是;
- A high-level programming language.
- Interpreted like Perl, Python, Tcl/TK.
- Object-oriented like Smalltalk, Eiffel, Ada, Java.
Why Ruby?
紅寶石起源於日本,現在在美國和歐洲也越來越受歡迎。以下因素有助於它的受歡迎程度;
- Easy to learn
- Open source (very liberal license)
- Rich libraries
- Very easy to extend
- Truly object-oriented
- Less coding with fewer bugs
- Helpful community
儘管我們有很多理由使用Ruby,但是在實現Ruby−之前,您可能還需要考慮一些缺點;
性能問題 &減;雖然它與Perl和Python相競爭,但它仍然是一種解釋性語言,我們無法將它與C或C++等高級程式語言進行比較。
線程模型−Ruby不使用本機線程。Ruby線程是在VM中模擬的,而不是作爲本機OS線程運行。
Sample Ruby Code
下面是一個列印「Hello Ruby」的Ruby代碼示例
# The Hello Class class Hello def initialize( name ) @name = name.capitalize end def salute puts "Hello #{@name}!" end end # Create a new object h = Hello.new("Ruby") # Output "Hello Ruby!" h.salute
輸出−這將產生以下結果−
Hello Ruby!
Embedded Ruby
Ruby提供了一個名爲ERB(嵌入式Ruby)的程序,由Seki Masatoshi編寫。ERB允許您將Ruby代碼放入HTML文件中。ERB逐字閱讀,然後在某個時刻,當遇到嵌入到文檔中的Ruby代碼時,它開始執行Ruby代碼。
你只需要知道兩件事就可以準備一份ERB文件;
如果要執行某些Ruby代碼,請將其括在<%和%>之間
如果希望輸出代碼執行的結果,作爲輸出的一部分,請將代碼括在<%=和%>之間。
這裡有一個例子。將代碼保存在erbdemo.rb文件中。注意,Ruby文件的擴展名爲.rb−
<% page_title = "Demonstration of ERB" %> <% salutation = "Dear programmer," %> <html> <head> <title><%= page_title %></title> </head> <body> <p><%= salutation %></p> <p>This is an example of how ERB fills out a template.</p> </body> </html>
現在,使用命令行實用程序erb運行程序。
tp> erb erbdemo.rb
這將產生以下結果&負;
<html> <head> <title>Demonstration of ERb</title> </head> <body> <p>Dear programmer,</p> <p>This is an example of how ERb fills out a template.</p> </body> </html>
What is Rails?
一個非常高效的web應用程式框架。
大衛·海涅梅爾·漢森用紅寶石寫的。
使用Rails開發web應用程式的速度至少是使用典型Java框架的10倍。
一個用於開發資料庫支持的web應用程式的開源Ruby框架。
使用資料庫架構配置代碼。
不需要編譯階段。
Full Stack Framework
包括使用模型-視圖-控制器模式創建資料庫驅動的web應用程式所需的所有內容。
作爲一個完整的堆棧框架,意味著所有層都可以無縫地與更少的代碼一起工作。
比其他框架需要更少的代碼行。
Convention over Configuration
Rails會避開配置文件,而傾向於使用約定、反射和動態運行時擴展。
您的應用程式代碼和運行中的資料庫已經包含了Rails需要知道的一切!
Rails Strengths
Rails包含了一些使您更有效率的特性,下面的許多特性是在其他特性的基礎上構建的。
Metaprogramming
當其他框架從頭開始使用大量代碼生成時,Rail框架使用元編程技術來編寫程序。Ruby是元編程的最佳語言之一,Rails很好地使用了這一功能。Rails也使用代碼生成,但更依賴於元編程來完成繁重的工作。
Active Record
Rails引入了Active Record框架,它將對象保存到資料庫中。活動記錄的Rails版本發現資料庫模式中的列,並使用元編程將它們自動附加到域對象。
Convention over configuration
大多數.NET或Java的web開發框架都會強制您編寫配置代碼頁。如果遵循建議的命名約定,Rails不需要太多配置。
Scaffolding
您經常在開發的早期階段創建臨時代碼,以幫助快速啓動應用程式並查看主要組件如何協同工作。Rails會自動創建您需要的大部分腳手架。
Built-in testing
Rails創建簡單的自動化測試,然後可以擴展。Rails還提供了稱爲wireless和fixture的支持代碼,使測試用例更易於編寫和運行。然後Ruby可以使用rake實用程序執行所有的自動化測試。
Three environments
Rails提供了三個默認環境:開發、測試和生產。每種方式的行爲稍有不同,使您的整個軟體開發周期更容易。例如,Rails爲每個測試運行創建一個新的測試資料庫副本。
Ruby on Rails - Installation
要使用Ruby on Rails框架開發web應用程式,需要安裝以下軟體−
- Ruby
- The Rails Framework
- A Web Server
- A Database System
我們假設您已經在計算機上安裝了Web伺服器和資料庫系統。您可以使用Ruby附帶的WEBrick Web伺服器。然而,大多數網站在生產中使用Apache或lightTPD web伺服器。
Rails可以與許多資料庫系統一起工作,包括MySQL、PostgreSQL、SQLite、Oracle、DB2和SQL Server。請參閱相應的資料庫系統安裝手冊來設置資料庫。
讓我們看看Windows和Linux上Rails的安裝說明。
Rails Installation on Windows
按照下面給出的步驟安裝Ruby on Rails。
Step 1: Check Ruby Version
首先,檢查是否已經安裝了Ruby。打開命令提示符並鍵入ruby-v。如果Ruby響應,並且它顯示了2.2.2或更高版本號,那麼輸入gem--version。如果沒有錯誤,請跳過安裝Ruby步驟。否則,我們將安裝一個新的Ruby。
Step 2: Install Ruby
如果沒有安裝Ruby,那麼從rubyinstaller.org下載安裝包。按照下載連結,並運行生成的安裝程序。這是一個exe文件rubyinstaller-2.2.2.x.exe,將在單擊時安裝。這是一個很小的包裹,你會得到RubyGems以及這個包裹。有關詳細信息,請查看發行說明。
Step 3: Install Rails
安裝Rails−加載Rubygems後,您可以通過命令行使用以下命令安裝所有Rails及其依賴項−
C:\> gem install rails
Note − The above command may take some time to install all dependencies. Make sure you are connected to the internet while installing gems dependencies.
Step 4: Check Rails Version
Use the following command to check the rails version.
C:\> rails -v
輸出
Rails 4.2.4
Congratulations! You are now on Rails over Windows.
Rails Installation on Linux
We are installing Ruby On Rails on Linux using rbenv. It is a lightweight Ruby Version Management Tool. The rbenv provides an easy installation procedure to manage various versions of Ruby, and a solid environment for developing Ruby on Rails applications.
Follow the steps given below to install Ruby on Rails using rbenv tool.
Step 1: Install Prerequisite Dependencies
First of all, we have to install git - core and some ruby dependences that help to install Ruby on Rails. Use the following command for installing Rails dependencies using yum.
tp> sudo yum install -y git-core zlib zlib-devel gcc-c++ patch readline readline-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison curl sqlite-devel
Step 2: Install rbenv
Now we will install rbenv and set the appropriate environment variables. Use the following set of commands to get rbenv for git repository.
tp> git clone git://github.com/sstephenson/rbenv.git .rbenv tp> echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile tp> echo 'eval "$(rbenv init -)"' >> ~/.bash_profile tp> exec $SHELL tp> git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build tp> echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' << ~/.bash_profile tp> exec $SHELL
Step 3: Install Ruby
Before installing Ruby, determine which version of Ruby you want to install. We will install Ruby 2.2.3. Use the following command for installing Ruby.
tp> rbenv install -v 2.2.3
Use the following command for setting up the current Ruby version as default.
tp> rbenv global 2.2.3
Use the following command to verify the Ruby version.
tp> ruby -v
輸出
ruby 2.2.3p173 (2015-08-18 revivion 51636) [X86_64-linux]
Ruby爲安裝支持的依賴項提供了一個關鍵字gem,我們稱之爲gem。如果不想安裝Ruby gems的文檔,請使用以下命令。
tp> echo "gem: --no-document" > ~/.gemrc
此後,最好安裝Bundler gem,因爲它有助於管理應用程式依賴項。使用以下命令安裝bundler gem。
tp> gem install bundler
Step 4: Install Rails
使用以下命令安裝Rails版本4.2.4。
tp> install rails -v 4.2.4
使用以下命令使Rails可執行文件可用。
tp> rbenv rehash
使用以下命令檢查rails版本。
tp> rails -v
輸出
tp> Rails 4.2.4
Ruby on Rails框架需要JavaScript運行時環境(Node.js)來管理Rails的特性。接下來,我們將看到如何使用Node.js來管理資產管道,這是一個Rails特性。
Step 5: Install JavaScript Runtime
讓我們從Yum存儲庫安裝Node.js。我們將從EPEL-yum存儲庫中獲取Node.js。使用以下命令將EPEL包添加到yum存儲庫。
tp> sudo yum -y install epel-release
使用以下命令安裝Node.js包。
tp> sudo yum install nodejs
祝賀 你!你現在在Linux上運行Rails。
Step 6: Install Database
默認情況下,Rails使用sqlite3,但您可能希望安裝MySQL、PostgreSQL或其他RDBMS。這是可選的;如果您已經安裝了資料庫,那麼您可以跳過這一步,並且不必安裝資料庫來啓動rails伺服器。在本教程中,我們將使用PostgreSQL資料庫。因此,請使用以下命令安裝PostgreSQL。
tp> sudo yum install postgresql-server postgresql-contrib
接受提示,用ay響應。使用以下命令創建PostgreSQl資料庫羣集。
tp> sudo postgresql-setup initdb
使用以下命令啓動並啓用PostgreSQL。
tp> sudo systemctl start postgresql tp> sudo systemctl enable postgresql
Keeping Rails Up-to-Date
假設您已經使用RubyGems安裝了Rails,那麼保持它是最新的相對容易。我們可以在Windows和Linux平台上使用相同的命令。使用以下命令−
tp> gem update rails
輸出
下面的螢幕截圖顯示了一個Windows命令提示符。Linux終端也提供相同的輸出。
這將自動更新您的Rails安裝。下次重新啓動應用程式時,它將使用最新版本的Rails。使用此命令時,請確保已連接到internet。
Installation Verification
您可以驗證是否所有設置都符合您的要求。使用以下命令創建演示項目。
tp> rails new demo
輸出
它將產生一個鐵路示範項目;我們稍後將討論。目前我們必須檢查環境是否已設置。接下來,使用以下命令在您的計算機上運行WEBrick web伺服器。
tp> cd demo tp> rails server
它將生成啓動伺服器的自動代碼
現在打開您的瀏覽器並鍵入以下−
http://localhost:3000
它應該顯示一條信息,比如「歡迎登機」或「恭喜」。
Ruby on Rails - Framework
框架是爲您編寫大部分應用程式的程序、程序集和/或代碼庫。當您使用框架時,您的工作是編寫應用程式的各個部分,使其完成您想要的特定任務。
當您打算編寫一個Rails應用程式時,除了配置和其他家務之外,您必須執行三個主要任務&負;
描述並建模應用程式的域−域是應用程式的整體。域名可以是音樂商店、大學、約會服務、地址簿或硬體清單。所以在這裡你必須弄清楚它是什麼,宇宙中存在著什麼實體,以及其中的元素是如何相互聯繫的。這相當於爲資料庫結構建模,以保留實體及其關係。
指定此域中可能發生的情況−域模型是靜態的;必須使其成爲動態的。地址可以添加到通訊簿中。樂譜可以從音樂商店購買。用戶可以登錄約會服務。學生可以在大學註冊上課。您需要確定域元素可以參與的所有可能的方案或操作。
選擇並設計域的公共可用視圖−此時,您可以開始使用Web瀏覽器進行思考。一旦您確定您的域中有學生,並且他們可以註冊課程,您就可以設想一個歡迎頁面、一個註冊頁面和一個確認頁面等。這些頁面或視圖中的每一個都向用戶展示了在某一點上的情況。
基於以上三個任務,Ruby on Rails處理了一個模型/視圖/控制器(Model/View/Controller,MVC)框架。
Ruby on Rails MVC Framework
控制器原理將應用程式的工作劃分爲三個獨立但緊密協作的子系統。
Model (ActiveRecord )
它維護對象和資料庫之間的關係,並處理驗證、關聯、事務等。
這個子系統是在ActiveRecord庫中實現的,ActiveRecord庫提供了一個接口和關係資料庫中的表與處理資料庫記錄的Ruby程序代碼之間的綁定。Ruby方法名是從資料庫表的欄位名自動生成的。
View ( ActionView )
它是特定格式的數據表示,由控制器決定顯示數據而觸發。它們是基於腳本的模板系統,如JSP、ASP、PHP,並且非常容易與AJAX技術集成。
該子系統是在ActionView庫中實現的,ActionView庫是一個基於嵌入式Ruby(ERb)的系統,用於定義數據表示的表示模板。每個到Rails應用程式的Web連接都會顯示一個視圖。
Controller ( ActionController )
應用程式中的一種功能,它一方面引導通信量,查詢模型中的特定數據,另一方面,將數據(搜索、排序、消息傳遞)組織成符合給定視圖需要的形式。
這個子系統在ActionController中實現,ActionController是位於ActiveRecord(資料庫接口)和ActionView(表示引擎)之間的數據代理。
Pictorial Representation of MVC Framework
下面給出了Ruby on Rails框架的一個圖形表示−
Directory Representation of MVC Framework
假設在Linux上安裝了一個標準的默認安裝,您會發現它們是這樣的−
tp> cd /usr/local/lib/ruby/gems/2.2.0/gems tp> ls
您將看到子目錄包括(但不限於)以下−
- actionpack-x.y.z
- activerecord-x.y.z
- rails-x.y.z
通過windows安裝,您可以找到這樣的文件;
tp>cd ruby\lib\ruby\gems\2.2.0\gems ruby\lib\ruby\gems\2.2.0\gems\>dir
您將看到子目錄包括(但不限於)以下−
ActionView和ActionController捆綁在ActionPack下。
ActiveRecord提供了一系列編程技術和快捷方式,用於處理SQL資料庫中的數據。ActionController和ActionView提供了操作和顯示數據的工具。鐵軌把它們綁在一起。
Ruby on Rails - Directory Structure
當使用Rails助手腳本創建應用程式時,它會爲應用程式創建整個目錄結構。Rails知道在這個結構中哪裡可以找到它需要的東西,所以您不必提供任何輸入。
下面是在創建應用程式時由helper腳本創建的目錄樹的頂層視圖。除了版本之間的細微變化之外,每個Rails項目都將具有相同的結構,具有相同的命名約定。這種一致性爲您提供了巨大的優勢;您可以在Rails項目之間快速移動,而無需重新學習項目的組織結構。
爲了理解這個目錄結構,讓我們使用在安裝一章中創建的demo應用程式。它可以使用一個簡單的helper命令創建。
現在,進入demo應用程式根目錄,如下所示−
tp> cd demo demo> dir
您將在Windows中找到一個目錄結構,如下所示−
現在讓我們解釋一下每個目錄的用途
app−它組織您的應用程式組件。它有包含視圖(視圖和幫助程序)、控制器(控制器)和後端業務邏輯(模型)的子目錄。
app/controllers子目錄是Rails查找控制器類的地方。控制器處理來自用戶的web請求。
app/helpers−helpers子目錄保存用於幫助模型、視圖和控制器類的任何helper類。這有助於保持模型、視圖和控制器代碼的小、集中和整潔。
app/model s−models子目錄保存建模的類,並包裝存儲在應用程式資料庫中的數據。在大多數框架中,應用程式的這一部分會變得相當混亂、乏味、冗長和容易出錯。Rails讓它變得非常簡單!
app/view−view s子目錄保存顯示模板,用應用程式中的數據填充,轉換爲HTML,然後返回用戶瀏覽器。
app/view/layouts−保存要與視圖一起使用的布局的模板文件。這爲包裝視圖的常見頁眉/頁腳方法建模。在視圖中,使用「布局:默認」定義布局,並創建名爲default.html.erb的文件。在default.html.erb中,調用<%yield%>以使用此布局呈現視圖。
components−此目錄保存組件、捆綁模型、視圖和控制器的小型自包含應用程式。
config−此目錄包含應用程式需要的少量配置代碼,包括資料庫配置(在database.yml中)、Rails環境結構(environment.rb)和傳入web請求的路由(routes.rb)。您還可以使用environments目錄中的文件爲測試、開發和部署定製三個Rails環境的行爲。
db−通常,Rails應用程式將具有訪問關係資料庫表的模型對象。您可以使用創建的腳本管理關係資料庫並將其放置在此目錄中。
doc−Ruby有一個稱爲RubyDoc的框架,它可以自動爲您創建的代碼生成文檔。您可以幫助RubyDoc在代碼中添加注釋。這個目錄保存所有RubyDoc生成的Rails和應用程式文檔。
lib−您將把庫放在這裡,除非它們明確屬於其他地方(如供應商庫)。
這裡是日誌−錯誤日誌。Rails創建腳本來幫助您管理各種錯誤日誌。您將找到伺服器(server.log)和每個Rails環境(development.log、test.log和production.log)的單獨日誌。
public−與web伺服器的public目錄類似,此目錄包含不更改的web文件,例如JavaScript文件(public/javascripts)、圖形(public/images)、樣式表(public/stylesheets)和HTML文件(public)。
script−此目錄保存用於啓動和管理將用於Rails的各種工具的腳本。例如,有生成代碼(generate)和啓動web伺服器(server)的腳本。
test−您編寫的測試和Rails爲您創建的測試都在這裡。您將看到mock(mock)、unit tests(unit)、fixture(fixture)和functional tests(functional)的子目錄。
tmp−Rails使用此目錄保存臨時文件以進行中間處理。
供應商−由第三方供應商提供的庫(如基本Rails發行版以外的安全庫或資料庫實用程序)轉到此處。
除了這些目錄之外,demo目錄中還有兩個文件可用。
自述文件−此文件包含有關Rail應用程式的基本詳細信息以及上述目錄結構的說明。
Rakefile−此文件類似於Unix Makefile,它有助於構建、打包和測試Rails代碼。這將由隨Ruby安裝一起提供的rake實用程序使用。
Ruby on Rails - Examples
在本章中,我們將創建一個簡單但可操作的在線圖書館系統來保存和管理圖書。
這個應用程式有一個基本的架構,將使用兩個ActiveRecord模型來描述存儲的數據類型;
- Books, which describes an actual listing.
- Subject, which is used to group books together.
Workflow for Creating Rails Applications
創建Rails應用程式的推薦工作流程如下所示;
使用rails命令創建應用程式的基本框架。
在PostgreSQL伺服器上創建一個資料庫來保存數據。
配置應用程式以了解資料庫的位置及其登錄憑據。
創建Rails活動記錄(模型),因爲它們是您將在控制器中使用的業務對象。
生成簡化資料庫表和列的創建和維護的遷移。
編寫控制器代碼以在應用程式中使用。
創建視圖以通過用戶界面顯示數據。
所以,讓我們從創建庫應用程式開始。
Creating an Empty Rails Web Application
Rails既是一個運行時web應用程式框架,也是一組幫助腳本,可以自動執行開發web應用程式時所做的許多事情。在這一步中,我們將使用一個這樣的helper腳本來創建整個目錄結構和啓動庫系統應用程式的初始文件集。
進入ruby安裝目錄創建應用程式。
運行以下命令爲庫應用程式創建骨架。它將在當前目錄中創建目錄結構。
tp> rails new library
這將爲庫應用程式創建一個子目錄,其中包含空Rails應用程式的文件夾和文件的完整目錄樹。檢查應用程式的完整目錄結構。有關更多詳細信息,請查看rails目錄結構。
我們的大部分開發工作將是在library/app子目錄中創建和編輯文件。下面是如何使用它們的簡要介紹;
controllers子目錄是Rails查找控制器類的位置。控制器處理來自用戶的web請求。
視圖子目錄保存顯示模板,以便用應用程式中的數據填充、轉換爲HTML並返回用戶瀏覽器。
model s子目錄保存建模的類,並包裝存儲在應用程式資料庫中的數據。在大多數框架中,應用程式的這一部分會變得相當混亂、乏味、冗長和容易出錯。Rails使它非常簡單。
helpers子目錄包含用於幫助模型、視圖和控制器類的任何helper類。這有助於保持模型、視圖和控制器代碼的小、集中和整潔。
Starting Web Server
Rails web應用程式幾乎可以在任何web伺服器下運行,但是開發railsweb應用程式最方便的方法是使用內置的webrickweb伺服器。讓我們啓動這個web伺服器,然後瀏覽到我們的空庫應用程式−
此伺服器將從應用程式目錄啓動,如下所示。它在3000號港口運行。
tp> cd ruby\library tp\ruby\library\> Rails server
它生成啓動伺服器的自動代碼,如下所示−
這將啓動WEBrick web伺服器。
現在打開瀏覽器並瀏覽到http://127.0.0.1:3000。如果一切順利,那麼您應該看到來自WEBrick的問候信息,否則您的設置有問題。如果一切順利,它將產生如下輸出。
What is next?
下一章將解釋如何爲應用程式創建資料庫,以及訪問這些創建的資料庫所需的配置。
此外,我們將看到什麼是Rails遷移,以及如何使用它來維護資料庫表。
Ruby on Rails - Database Setup
在開始本章之前,請確保資料庫伺服器已啓動並正在運行。Ruby on Rails建議創建三個資料庫,分別用於開發、測試和生產環境。按照慣例,他們的名字應該是&;
- library_development
- library_production
- library_test
您應該初始化這三個程序,並爲它們創建具有完全讀寫權限的用戶和密碼。我們正在爲應用程式使用根用戶ID。
Database Setup for MySQL
在MySQL中,我們對應用程式使用根用戶ID。執行此操作的MySQL控制台會話類似於−
mysql> create database library_development; Query OK, 1 row affected (0.01 sec) mysql> grant all privileges on library_development.* to 'root'@'localhost' identified by 'password'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
您可以對另外兩個資料庫執行相同的操作library_production和library_test。
Configuring database.yml
此時,您需要讓Rails知道資料庫的用戶名和密碼。您可以在您創建的Rails應用程式的library\config子目錄中的文件database.yml中執行此操作。此文件包含MySQL資料庫的實時配置部分。在您使用的每個部分中,都需要更改用戶名和密碼行,以反映您所創建資料庫的權限。
當你完成的時候,它應該看起來像;
development: adapter: mysql database: library_development username: root password: [password] host: localhost test: adapter: mysql database: library_test username: root password: [password] host: localhost production: adapter: mysql database: library_production username: root password: [password] host: localhost
Database Setup for PostgreSQL
默認情況下,PostgreSQL不提供任何用戶。我們必須創建新用戶。使用以下命令創建名爲rubyuser的用戶。
tp> sudo -u postgres createuser rubyuser -s
如果要爲新用戶創建密碼,請使用以下命令。
tp> sudo -u postgres psql postgres=# \password rubyuser
使用以下命令創建資料庫庫開發。
postgres=# CREATE DATABASE library_development OWNER rubyuser; CREATE DATABASE
使用以下命令創建資料庫庫產品。
postgres=# CREATE DATABASE library_production OWNER rubyuser; CREATE DATABASE
使用以下命令創建資料庫庫測試。
postgres=# CREATE DATABASE library_test OWNER rubyuser; CREATE DATABASE
Pressctrl+d>to terminate possgresql.
Configuring database.yml
此時,您需要讓Rails知道資料庫的用戶名和密碼。您可以在您創建的Rails應用程式的library\config子目錄中的文件database.yml中執行此操作。此文件包含PostgreSQL資料庫的實時配置部分。在每個部分中,您都需要更改用戶名和密碼行,以反映您創建的資料庫的權限。
當你完成的時候,它應該是這樣的;
default: &default adapter: postgresql encoding: unicode development: adapter: postgresql encoding: unicode database: library_development username: rubyuser password: <Password for rubyuser> test: adapter: postgresql encoding: unicode database: library_test username: rubyuser password: <Password for rubyuser> production: adapter: postgresql encoding: unicode database: library_production username: rubyuser password: <Password for rubyuser>
What is Next?
接下來的兩章將解釋如何對資料庫表建模,以及如何使用Rails遷移來管理這些表。
Ruby on Rails - Active Records
Rails活動記錄是Rails提供的對象/關係映射(ORM)層。它緊跟標準ORM模型,如下所示;
- tables map to classes,
- rows map to objects and
- columns map to object attributes.
Rails活動記錄在關係資料庫中的表和處理資料庫記錄的Ruby程序代碼之間提供接口和綁定。Ruby方法名是從資料庫表的欄位名自動生成的。
每個活動記錄對象都有用於資料庫訪問的CRUD(C創建、R讀取、u更新和D刪除)方法。此策略允許在資料庫表和應用程式對象之間進行簡單的設計和直接映射。
Translating a Domain Model into SQL
將域模型轉換成SQL通常是直接的,只要您記住必須編寫對Rails友好的SQL。實際上,你必須遵守某些規則;
每個實體(如book)都在資料庫中獲取一個以其命名的表,但使用複數形式(books)。
每個這樣的實體匹配表都有一個名爲id的欄位,該欄位包含插入表中的每條記錄的唯一整數。
給定實體x和實體y,如果實體y屬於實體x,那麼表y有一個名爲x_id的欄位。
任何表中的大部分欄位存儲該實體的簡單屬性(任何數字或字符串)的值。
Creating Active Record Files (Models)
要爲庫應用程式的實體創建活動記錄文件(在上一章中介紹),請從應用程式目錄的頂層發出以下命令。
library\> ruby script/generate model Book library\> ruby script/generate model Subject
上面的rails generate model book命令生成如下所示的自動代碼−
您告訴生成器創建名爲Book和Subject的模型,以存儲書籍和主題的實例。請注意,您正在將書籍和主題大寫,並使用單數形式。這是一個Rails範例,每次創建模型時都應該遵循它。
當您使用generate工具時,Rails會創建一個實際的模型文件,其中包含您定義的模型和業務規則所特有的所有方法,一個用於執行測試驅動開發的單元測試文件,一個用於單元測試的示例數據文件(稱爲fixture),以及一個Rails遷移,它使創建資料庫表和列變得容易。
除了創建許多其他文件和目錄外,還將創建名爲book.rb和subject.rb的文件,其中包含app/models目錄中的框架定義。
book.rb−中提供的內容;
class Book < ActiveRecord::Base end
subject.rb−中提供的內容;
class Subject < ActiveRecord::Base end
Creating Associations between Models
當rails應用程式中有多個模型時,需要在這些模型之間創建連接。你可以通過聯想來做到這一點。活動記錄支持三種類型的關聯−
一對一−當一個項正好有另一個項時,就存在一對一關係。例如,一個人只有一個生日,或者一條狗只有一個主人。
當一個對象可以是許多其他對象的成員時,就存在一對多關係。例如,一門學科可以有許多書。
當第一個對象與第二個對象中的一個或多個相關,而第二個對象與第一個對象中的一個或多個相關時,就存在多對多關係。
通過向模型中添加聲明來指示這些關聯:hasúone、hasúmany、belongsúto,以及hasúandúbelongs戔to戔many。
現在,您需要告訴Rails您希望在庫數據系統中建立什麼關係。爲此,請將book.rb和subject.rb修改爲如下所示&負;
class Book < ActiveRecord::Base belongs_to :subject end
我們在上面的例子中使用了一個單獨的主題,因爲一本書可以屬於一個單獨的主題。
class Subject < ActiveRecord::Base has_many :books end
我們在這裡使用了複數本,因爲一個主題可以有多本書。
Implementing Validations on Models
驗證的實現是在Rails模型中完成的。您輸入到資料庫中的數據是在實際的Rails模型中定義的,因此只有在相同的位置定義哪些有效數據才有意義。
驗證結果爲&負;
標題欄位的值不應爲空。
價格欄位的值應爲數字。
打開app\model子目錄中的book.rb,並輸入以下驗證值−
class Book < ActiveRecord::Base belongs_to :subject validates_presence_of :title validates_numericality_of :price, :message=>"Error Message" end
驗證是否存在−可防止「非空」欄位丟失用戶輸入。
驗證−的數字性,防止用戶輸入非數字數據。
除了上面提到的驗證之外,還有其他常見的驗證。檢查rails快速指南。
What is Next?
在下一章中,我們將學習Rails遷移,它允許您使用Ruby定義對資料庫模式的更改,從而可以使用版本控制系統使事情與實際代碼保持同步。
Ruby on Rails - Migrations
Rails遷移允許您使用Ruby定義對資料庫模式的更改,從而可以使用版本控制系統使事情與實際代碼保持同步。
這有很多用途,包括&負;
開發團隊−如果一個人更改了模式,其他開發人員只需更新並運行「rake migrate」。
當您推出新版本以使資料庫也保持最新時,生產伺服器−運行「rake migrate」。
多台機器−如果您同時在台式機和筆記本電腦上開發,或者在多個位置開發,遷移可以幫助您使它們保持同步。
What Can Rails Migration Do?
- create_table(name, options)
- drop_table(name)
- rename_table(old_name, new_name)
- add_column(table_name, column_name, type, options)
- rename_column(table_name, column_name, new_column_name)
- change_column(table_name, column_name, type, options)
- remove_column(table_name, column_name)
- add_index(table_name, column_name, index_type)
- remove_index(table_name, column_name)
遷移支持所有基本數據類型−以下是遷移支持的數據類型列表−
字符串−用於小數據類型,如標題。
文本−用於較長的文本數據片段,如說明。
所有數字的整數&minus。
浮點數−表示小數。
日期時間和時間戳−將日期和時間存儲到列中。
日期和時間−只存儲日期或時間。
二進位−用於存儲圖像、音頻或電影等數據。
用於存儲真值或假值的布爾值。
有效列選項是−以下是有效列選項的列表。
限制(:limit=>>%35;8220;50&\3521;)
默認值(:default=>“blah”)
null(:null=>false表示不爲null)
注意−Rails遷移完成的活動可以使用任何前端GUI完成,也可以直接在SQL提示符下完成,但是Rails遷移使所有這些活動都非常容易。
有關這些的詳細信息,請參見Rails api。
Create the Migrations
下面是創建遷移的通用語法−
application_dir> rails generate migration table_name
這將創建文件db/migrate/001_table_name.rb。遷移文件包含描述資料庫表的數據結構的基本Ruby語法。
注意:在運行遷移生成器之前,建議清除模型生成器生成的現有遷移。
我們將創建與三個表對應的兩個遷移−書籍和主題。
圖書遷移應按以下方式進行&負;
tp> cd library library> rails generate migration books
上面的命令生成以下代碼。
主題遷移應如下所示;
tp> cd library library> rails generate migration subjects
上面的命令生成以下代碼。
注意,在創建遷移時,您對book和subject以及複數形式使用小寫。這是一個Rails範例,每次創建遷移時都應該遵循它。
Edit the Code
轉到應用程式的db/migrate子目錄,使用任何簡單的文本編輯器逐個編輯每個文件。
修改001_books.rb如下&減號;
ID列將自動創建,所以不要在這裡也這樣做。
class Books < ActiveRecord::Migration def self.up create_table :books do |t| t.column :title, :string, :limit => 32, :null => false t.column :price, :float t.column :subject_id, :integer t.column :description, :text t.column :created_at, :timestamp end end def self.down drop_table :books end end
當遷移到新版本時,使用方法self.up,如果需要,使用方法self.down回滾任何更改。此時,上面的腳本將用於創建books表。
修改002_subjects.rb如下&負;
class Subjects < ActiveRecord::Migration def self.up create_table :subjects do |t| t.column :name, :string end Subject.create :name => "Physics" Subject.create :name => "Mathematics" Subject.create :name => "Chemistry" Subject.create :name => "Psychology" Subject.create :name => "Geography" end def self.down drop_table :subjects end end
上面的腳本將用於創建subjects表,並將在subjects表中創建五條記錄。
Run the Migration
現在您已經創建了所有必需的遷移文件。現在是對資料庫執行它們的時候了。爲此,請轉到命令提示符並轉到應用程式所在的庫目錄,然後按以下方式鍵入rake migrate−
library> rake db:migrate
這將創建一個「schema_info」表(如果該表不存在),用於跟蹤資料庫的當前版本-每個新遷移都將是一個新版本,並且任何新遷移都將運行,直到資料庫處於當前版本。
Rake是一個Ruby構建程序,類似於Unixmake程序,Rails利用它來簡化複雜任務的執行,比如更新資料庫結構等。
Running Migrations for Production and Test Databases
如果要指定要用於遷移的Rails環境,請使用Rails_ENV shell變量。
例如−
library> export RAILS_ENV = production library> rake db:migrate library> export RAILS_ENV = test library> rake db:migrate library> export RAILS_ENV = development library> rake db:migrate
注意−在Windows中,使用「set RAILS_ENV=production」而不是export命令。
What is Next?
現在我們有了資料庫和所需的表。在接下來的兩章中,我們將探討兩個重要的組件,稱爲Controller(ActionController)和View(ActionView)。
創建控制器(動作控制器)。
創建視圖(動作視圖)。
Ruby on Rails - Controller
Rails控制器是應用程式的邏輯中心。它協調用戶、視圖和模型之間的交互。管制員也是許多重要輔助服務的所在地。
它負責將外部請求路由到內部操作。它非常好地處理人們友好的網址。
它管理緩存,這可以給應用程式帶來數量級的性能提升。
它管理helper模塊,這些模塊擴展了視圖模板的功能,而不會增加它們的代碼。
它管理會話,給用戶留下與我們的應用程式進行交互的印象。
創建控制器的過程非常簡單,它與我們已經用於創建模型的過程類似。我們在這裡只創建一個控制器;
library\> rails generate controller Book
注意,你是大寫的書和使用單數形式。這是一個Rails範例,每次創建控制器時都應該遵循它。
這個命令完成了幾個任務,其中與此相關的是&負;
它創建一個名爲app/controllers/book_controller.rb的文件
如果您查看book_controller.rb,您會發現它如下所示;
class BookController < ApplicationController end
控制器類繼承自application Controller,這是controllers文件夾中的另一個文件:application.rb。
ApplicationController包含可以在所有控制器中運行的代碼,它繼承自RailsActionController::Base類。
到目前爲止,您還不需要擔心ApplicationController,所以讓我們在book\controller.rb中定義一些方法存根。根據您的需求,您可以在此文件中定義任意數量的函數。
將文件修改爲如下所示並保存更改。注意,你想給這些方法起什麼名字取決於你,但是最好給相關的名字。
class BookController < ApplicationController def list end def show end def new end def create end def edit end def update end def delete end end
現在讓我們逐一實現所有方法。
Implementing the list Method
list方法提供資料庫中所有書籍的列表。此功能將通過以下代碼行實現。在book_controller.rb文件中編輯以下行。
def list @books = Book.all end
list方法中的@books=Book.all行告訴Rails搜索books表並將找到的每一行存儲在@books實例對象中。
Implementing the show Method
show方法僅顯示一本書的更多詳細信息。此功能將通過以下代碼行實現。
def show @book = Book.find(params[:id]) end
show方法的@book=book.find(params[:id])行告訴Rails只查找在params[:id]中定義了id的圖書。
params對象是允許在方法調用之間傳遞值的容器。例如,當您在list方法調用的頁面上時,可以單擊特定圖書的連結,它通過params對象傳遞圖書的id,這樣show就可以找到特定的圖書。
Implementing the new Method
新方法讓Rails知道您將創建一個新對象。所以只需在這個方法中添加以下代碼。
def new @book = Book.new @subjects = Subject.all end
當您向用戶顯示一個頁面以接受用戶輸入時,將調用上述方法。在這裡,第二行從資料庫中獲取所有主題,並將它們放入一個名爲@subjects的數組中。
Implementing the create Method
一旦您使用HTML表單接受用戶輸入,就可以在資料庫中創建記錄了。要實現這一點,請編輯book_controller.rb中的create方法,使其與以下−匹配;
def create @book = Book.new(book_params) if @book.save redirect_to :action => 'list' else @subjects = Subject.all render :action => 'new' end end def book_params params.require(:books).permit(:title, :price, :subject_id, :description) end
第一行創建一個名爲@book的新實例變量,該變量保存從用戶提交的數據構建的book對象。book_params方法用於收集object:books中的所有欄位。數據是從要使用params對象創建的新方法傳遞的。
下一行是一個條件語句,如果對象正確保存到資料庫,則該語句將用戶重定向到list方法。如果不保存,則將用戶發送回新方法。redirect_to方法類似於在網頁上執行元刷新:它自動將您轉發到目的地,而無需任何用戶交互。
然後@subjects=Subject.all是必需的,以防它無法成功保存數據,並且變得與新選項類似。
Implementing the edit Method
edit方法看起來與show方法幾乎相同。這兩種方法都用於根據單個對象的id檢索該對象並將其顯示在頁面上。唯一的區別是show方法不可編輯。
def edit @book = Book.find(params[:id]) @subjects = Subject.all end
將調用此方法以在螢幕上顯示要由用戶修改的數據。第二行從資料庫中獲取所有主題,並將它們放入一個名爲@subjects的數組中。
Implementing the update Method
當用戶修改數據並希望將更改更新到資料庫中時,將在edit方法之後調用此方法。update方法類似於create方法,將用於更新資料庫中的現有書籍。
def update @book = Book.find(params[:id]) if @book.update_attributes(book_param) redirect_to :action => 'show', :id => @book else @subjects = Subject.all render :action => 'edit' end end def book_param params.require(:book).permit(:title, :price, :subject_id, :description) end
update_attributes方法與create使用的save方法類似,但它不會在資料庫中創建新行,而是覆蓋現有行的屬性。
然後@subjects=Subject.all行是必需的,如果它沒有成功保存數據,那麼它就變成類似於edit選項。
Implementing the delete Method
如果要從資料庫中刪除記錄,則將使用此方法。按如下方式實現此方法。
def delete Book.find(params[:id]).destroy redirect_to :action => 'list' end
第一行根據通過params對象傳遞的參數查找分類,然後使用destroy方法刪除它。第二行使用redirect_to call將用戶重定向到list方法。
Additional Methods to Display Subjects
假設你想給你的用戶一個基於給定主題的瀏覽所有書籍的工具。因此,可以在book_controller.rb中創建一個方法來顯示所有主題。假設方法名爲顯示主題−
def show_subjects @subject = Subject.find(params[:id]) end
最後,您的book_controller.rb文件將如下所示−
class BooksController < ApplicationController def list @books = Book.all end def show @book = Book.find(params[:id]) end def new @book = Book.new @subjects = Subject.all end def book_params params.require(:books).permit(:title, :price, :subject_id, :description) end def create @book = Book.new(book_params) if @book.save redirect_to :action => 'list' else @subjects = Subject.all render :action => 'new' end end def edit @book = Book.find(params[:id]) @subjects = Subject.all end def book_param params.require(:book).permit(:title, :price, :subject_id, :description) end def update @book = Book.find(params[:id]) if @book.update_attributes(book_param) redirect_to :action => 'show', :id => @book else @subjects = Subject.all render :action => 'edit' end end def delete Book.find(params[:id]).destroy redirect_to :action => 'list' end def show_subjects @subject = Subject.find(params[:id]) end end
現在保存控制器文件。
What is Next?
您已經創建了幾乎所有的方法,這些方法將在後端工作。接下來,我們將爲操作定義路由(url)。
Ruby on Rails - Routes
路由模塊提供了用原生Ruby重寫URL的功能。這是一種將傳入請求重定向到控制器和操作的方法。它取代了mod_重寫規則。最重要的是,Rails的路由可以與任何web伺服器一起工作。路由在app/config/Routes.rb中定義。
將創建路由看作是爲您的請求繪製地圖。地圖根據一些預定義的模式告訴他們去哪裡−
Rails.application.routes.draw do Pattern 1 tells some request to go to one place Pattern 2 tell them to go to another ... end
Example
讓我們考慮一下庫管理應用程式包含一個名爲BookController的控制器。我們必須爲那些在BookController類中定義爲方法的操作定義路由。
打開library/config/directory中的routes.rb文件並使用以下內容對其進行編輯。
Rails.application.routes.draw do get 'book/list' get 'book/new' post 'book/create' patch 'book/update' get 'book/list' get 'book/show' get 'book/edit' get 'book/delete' get 'book/update' get 'book/show_subjects' end
routes.rb文件定義了應用程式中可用的操作和操作類型,如get、post和patch。
使用下面的命令列出所有已定義的路由,這些路由對於跟蹤應用程式中的路由問題很有用,或者爲您提供對要熟悉的應用程式中的url的良好概述。
library> rake routes
What is Next?
接下來,我們將創建代碼來生成螢幕以顯示數據並從用戶處獲取輸入。
Ruby on Rails - Views
Rails視圖是一個ERb程序,它通過相互訪問的變量與控制器共享數據。
如果您查看庫應用程式的app/views目錄,您將看到每個控制器的一個子目錄,我們已經創建了:book。這些子目錄中的每一個子目錄都是在使用generate腳本創建同名控制器時自動創建的。
Rails讓您知道需要爲每個新方法創建視圖文件。在控制器中定義的每個方法都需要有一個與該方法同名的對應的erb文件,以顯示該方法正在收集的數據。
因此,讓我們爲book_controller.rb中定義的所有方法創建視圖文件。在執行這些視圖時,同時檢查這些操作是否適用於資料庫。
Creating View File for list Method
使用您喜愛的文本編輯器創建一個名爲list.html.erb的文件,並將其保存到app/views/book。創建並保存文件後,請刷新web瀏覽器。您應該看到一個空白頁;如果沒有,請檢查文件的拼寫,並確保它與控制器的方法完全相同。
現在,顯示實際內容。讓我們將以下代碼放入list.html.erb中。
<% if @books.blank? %> <p>There are not any books currently in the system.</p> <% else %> <p>These are the current books in our system</p> <ul id = "books"> <% @books.each do |c| %> <li><%= link_to c.title, {:action => 'show', :id => c.id} -%></li> <% end %> </ul> <% end %> <p><%= link_to "Add new Book", {:action => 'new' }%></p>
要執行的代碼是檢查@books數組中是否有任何對象。空白?如果數組爲空,則方法返回true;如果數組包含任何對象,則返回false。這個@books對象是在list方法內的controller中創建的。
標記之間的代碼是一個連結到方法調用。link_to的第一個參數是要在<a>標記之間顯示的文本。第二個參數是單擊連結時調用的操作。在本例中,它是show方法。最後一個參數是通過params對象傳遞的圖書的id。
現在,嘗試刷新您的瀏覽器,您應該會看到以下螢幕,因爲我們的庫中沒有任何書籍。
Creating View File for new Method
到現在爲止,我們的圖書館裡還沒有書。我們必須在系統中創建一些書籍。因此,讓我們設計一個視圖,它對應於book\controller.rb中定義的new方法。
使用您喜愛的文本編輯器創建一個名爲new.html.erb的文件,並將其保存到app/views/book。將以下代碼添加到new.html.erb文件中。
<h1>Add new book</h1> <%= form_tag :action => 'create' do %> <p><label for = "book_title">Title</label>: <%= text_field 'books', 'title' %></p> <p><label for = "book_price">Price</label>: <%= text_field 'books', 'price' %></p> <p><label for = "book_subject_id">Subject</label>: <%= collection_select(:books, :subject_id, @subjects, :id, :name, prompt: true) %></p> <p><label for = "book_description">Description</label><br/> <%= text_area 'books', 'description' %></p> <%= submit_tag "Create" %> <% end -%> <%= link_to 'Back', {:action => 'list'} %>
在這裡,form_tag方法使用提供給它的所有信息將Ruby代碼解釋爲一個常規的HTML<form>標記。例如,這個標記輸出以下HTML−
<form action = "/book/create" method = "post">
下一種方法是輸出文本欄位的文本欄位。文本欄位的參數是對象和欄位名。在本例中,對象是book,名稱是title。
名爲collection\u select的Rails方法,創建一個從數組(如@books one)構建的HTML選擇菜單。有五個參數,如下所示;
:book−正在操作的對象。在這種情況下,它是一個圖書對象。
:subject_id−保存書本時填充的欄位。
@books−正在使用的數組。
:id−存儲在資料庫中的值。就HTML而言,這是<option>標記的值參數。
:name−用戶在下拉菜單中看到的輸出。這是<選項>標記之間的值。
下一個使用的是提交標記,它輸出提交表單的「輸入」按鈕。最後,還有一個end方法,它簡單地轉換爲</form>。
轉到瀏覽器並訪問http://localhost:3000/book/new。這將顯示以下螢幕。
在此表單中輸入一些數據,然後單擊「創建」按鈕。在這裡,我在欄位中添加了以下詳細信息&負;
Title: Advance Physics Price: 390 Subject: Physics Description: This is test to create new book
當您單擊Create按鈕時,它將調用Create方法,該方法不需要任何視圖,因爲該方法使用list或new方法來查看結果。因此,當您單擊Create按鈕時,數據應該成功提交並重定向到list頁面,在該頁面中,您現在有一個項目列示如下−
如果單擊該連結,您將看到另一個模板丟失錯誤,因爲您尚未爲show method創建模板文件。
Creating View File for show Method
此方法將顯示有關庫中任何可用圖書的完整詳細信息。在app/views/book下創建一個show.html.erb文件,並用以下代碼填充它−
<h1><%= @book.title %></h1> <p> <strong>Price: </strong> $<%= @book.price %><br /> <strong>Subject :</strong> <%= @book.subject.name %><br /> <strong>Created Date:</strong> <%= @book.created_at %><br /> </p> <p><%= @book.description %></p> <hr /> <%= link_to 'Back', {:action => 'list'} %>
這是您第一次充分利用關聯,它使您能夠輕鬆地從相關對象中提取數據。
使用的格式是@variable.relatedObject.column。在本例中,您可以使用歸屬於關聯通過@book變量拉取主題的名稱值。如果單擊任何列出的記錄,它將顯示以下螢幕。
Creating View File for edit Method
創建一個名爲edit.html.erb的新文件並將其保存在app/views/book中。用以下代碼填充它−
<h1>Edit Book Detail</h1> <%= form_for @book, :url =>{:action => "update", :id =>@book} do |f| %> <p>Title: <%= f.text_field 'title' %></p> <p>Price: <%= f.text_field 'price' %></p> <p>Subject: <%= f.collection_select :subject_id, Subject.all, :id, :name %></p> <p>Description<br/> <%= f.text_area 'description' %></p> <%= f.submit "Save changes" %> <% end %> <%= link_to 'Back', {:action => 'list' } %>
此代碼與new方法非常相似,除了要更新的操作,而不是創建和定義id。
在這個場景中,我們使用form_for標記表單操作。它的性能將優於form_tag。爲什麼,因爲它會很容易地創建與模型的交互。因此,當您需要模型和表單欄位之間的交互時,最好使用form_作爲標記。
此時,我們需要對list方法的視圖文件進行一些修改。轉到<li><li>元素並將其修改爲如下所示;
<li> <%= link_to c.title, {:action => "show", :id => c.id} -%> <b> <%= link_to 'Edit', {:action => "edit", :id => c.id} %></b> </li>
現在,嘗試使用http://localhost:3000/book/list來瀏覽書籍。它將爲您提供所有書籍的列表以及Edit選項。單擊「編輯」選項時,將出現下一個螢幕,如下所示−
現在,您可以編輯此信息,然後單擊保存更改按鈕。這將導致調用控制器文件中可用的update方法,並更新所有更改的屬性。注意,update方法不需要任何視圖文件,因爲它使用show或edit方法來顯示其結果。
Creating View File for delete Method
使用Ruby on Rails從資料庫中刪除信息幾乎太容易了。您不需要爲delete方法編寫任何視圖代碼,因爲此方法使用list方法來顯示結果。所以,讓我們再次修改list.html.erb並添加一個刪除連結。
轉到<li><li>元素並將其修改爲如下所示;
<li> <%= link_to c.title, {:action => 'show', :id => c.id} -%> <b> <%= link_to 'Edit', {:action => 'edit', :id => c.id} %></b> <b> <%= link_to "Delete", {:action => 'delete', :id => c.id}, :confirm => "Are you sure you want to delete this item?" %></b> </li>
:confirm參數顯示一個JavaScript確認框,詢問您是否真的要執行該操作。如果用戶單擊「確定」,則操作將繼續,並刪除該項。
現在,嘗試使用http://localhost:3000/book/list瀏覽書籍。它將爲您提供所有書籍的列表以及編輯和刪除選項,如下所示−
現在使用Delete選項,您可以刪除任何列出的記錄。
Creating View File for show_subjects Method
在app/views/book目錄中創建一個新文件show_subjects.html.erb,並向其中添加以下代碼−
<h1><%= @subject.name -%></h1> <ul> <% @subject.books.each do |c| %> <li><%= link_to c.title, :action => "show", :id => c.id -%></li> <% end %> </ul>
通過遍歷單個主題的多個圖書列表,可以利用關聯。
現在修改show.html.erb的Subject:line,以便Subject列表顯示一個連結。
<strong>Subject: </strong> <%= link_to @book.subject.name, :action => "show_subjects", :id => @book.subject.id %><br />
這將在索引頁上輸出主題列表,以便用戶可以直接訪問它們。
修改list.html.erb將以下內容添加到文件頂部−
<ul id = "subjects"> <% Subject.find(:all).each do |c| %> <li><%= link_to c.name, :action => "show_subjects", :id => c.id %></li> <% end %> </ul>
現在嘗試使用http://localhost:3000/book/list瀏覽書籍。它將顯示所有主題與連結,以便您可以瀏覽所有與該主題相關的書籍。
What is Next?
希望您現在對Rails的所有操作感到滿意。
下一章將解釋如何使用布局以更好的方式放置數據。我們將向您展示如何在Rails應用程式中使用CSS。
Ruby on Rails - Layouts
布局定義HTML頁面的周圍環境。這是定義最終輸出的共同外觀的地方。布局文件位於app/views/layouts中。
這個過程包括定義一個布局模板,然後讓控制器知道它存在並使用它。首先,讓我們創建模板。
將名爲standard.html.erb的新文件添加到app/views/layouts。您可以通過文件名讓控制器知道要使用什麼模板,因此建議遵循相同的命名方案。
將以下代碼添加到新的standard.html.erb文件中並保存所做的更改;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = iso-8859-1" /> <meta http-equiv = "Content-Language" content = "en-us" /> <title>Library Info System</title> <%= stylesheet_link_tag "style" %> </head> <body id = "library"> <div id = "container"> <div id = "header"> <h1>Library Info System</h1> <h3>Library powered by Ruby on Rails</h3> </div> <div id = "content"> <%= yield -%> </div> <div id = "sidebar"></div> </div> </body> </html>
您剛才添加的所有內容都是標準的HTML元素,只有兩行除外。樣式表連結標籤幫助程序方法輸出樣式表<連結>。在本例中,我們正在連結style.css樣式表。yield命令讓Rails知道應該爲這裡調用的方法放置html.erb。
現在打開book_controller.rb並在第一行下方添加以下行−
class BookController < ApplicationController layout 'standard' def list @books = Book.all end ...................
它指示控制器要使用standard.html.erb文件中提供的布局。現在嘗試瀏覽將產生以下螢幕的書籍。
Adding Style Sheet
到目前爲止,我們還沒有創建任何樣式表,因此Rails使用默認樣式表。現在,讓我們創建一個名爲style.css的新文件,並將其保存在/public/stylesheets中。將以下代碼添加到此文件中。
body { font-family: Helvetica, Geneva, Arial, sans-serif; font-size: small; font-color: #000; background-color: #fff; } a:link, a:active, a:visited { color: #CD0000; } input { margin-bottom: 5px; } p { line-height: 150%; } div#container { width: 760px; margin: 0 auto; } div#header { text-align: center; padding-bottom: 15px; } div#content { float: left; width: 450px; padding: 10px; } div#content h3 { margin-top: 15px; } ul#books { list-style-type: none; } ul#books li { line-height: 140%; } div#sidebar { width: 200px; margin-left: 480px; } ul#subjects { width: 700px; text-align: center; padding: 5px; background-color: #ececec; border: 1px solid #ccc; margin-bottom: 20px; } ul#subjects li { display: inline; padding-left: 5px; }
現在刷新您的瀏覽器並查看差異;
What is Next?
下一章將解釋如何使用Rails Scaffolding開發應用程式,使用戶能夠添加、刪除和修改任何資料庫中的記錄。
Ruby on Rails - Scaffolding
當您開發Rails應用程式時,特別是那些主要爲您提供資料庫中數據的簡單接口的應用程式,使用scaffold方法通常會很有用。
腳手架提供的不僅僅是廉價的演示刺激。這裡有一些好處;
您可以在用戶面前快速獲取代碼以獲得反饋。
你的動力來自更快的成功。
通過查看生成的代碼,您可以了解Rails是如何工作的。
你可以用腳手架作爲基礎來開始你的開發。
Scaffolding Example
爲了理解scaffolding,讓我們創建一個名爲cookbook的資料庫和一個名爲recipes的表。
Creating an Empty Rails Web Application
打開一個命令窗口並導航到要創建這個cookbookweb應用程式的位置。因此,運行以下命令創建一個完整的目錄結構。
tp> rails new cookbook
Setting up the Database
下面是創建資料庫的方法−
mysql> create database cookbook; Query OK, 1 row affected (0.01 sec) mysql> grant all privileges on cookbook.* to 'root'@'localhost' identified by 'password'; Query OK, 0 rows affected (0.00 sec) mysql> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)
To instruct Rails how to find the database, edit the configuration file cookbook\config\database.yml and change the database name to cookbook. Leave the password empty. 當你完成的時候,它應該是這樣的;
development: adapter: mysql database: cookbook username: root password: [password] host: localhost test: adapter: mysql database: cookbook username: root password: [password] host: localhost production: adapter: mysql database: cookbook username: root password: [password] host: localhost
Rails允許您使用不同的資料庫在開發模式、測試模式或生產模式下運行。此應用程式對每個應用程式使用相同的資料庫。
The Generated Scaffold Code
通過scaffold操作,Rails動態地生成它需要的所有代碼。通過將scaffold作爲腳本運行,我們可以將所有代碼寫入磁碟,在那裡我們可以對其進行調查,然後開始根據我們的需求對其進行裁剪。
現在,讓我們再次開始使用Scaffold helper腳本手動生成Scaffold代碼;
cookbook> rails generate scaffold recipe
它生成如下所示的自動文件;
The Controller
讓我們看看控制器後面的代碼。此代碼由scaffold生成器生成。如果您打開app/controllers/recipes_controller.rb,您將發現以下內容&負;
class RecipesController < ApplicationController before_action :set_recipe, only: [:show, :edit, :update, :destroy] # GET /recipes # GET /recipes.json def index @recipes = Recipe.all end # GET /recipes/1 # GET /recipes/1.json def show end # GET /recipes/new def new @recipe = Recipe.new end # GET /recipes/1/edit def edit end # POST /recipes # POST /recipes.json def create @recipe = Recipe.new(recipe_params) respond_to do |format| if @recipe.save format.html { redirect_to @recipe, notice: 'Recipe was successfully created.' } format.json { render :show, status: :created, location: @recipe } else format.html { render :new } format.json { render json: @recipe.errors, status: :unprocessable_entity } end end end # PATCH/PUT /recipes/1 # PATCH/PUT /recipes/1.json def update respond_to do |format| if @recipe.update(recipe_params) format.html { redirect_to @recipe, notice: 'Recipe was successfully updated.' } format.json { render :show, status: :ok, location: @recipe } else format.html { render :edit } format.json { render json: @recipe.errors, status: :unprocessable_entity } end end end # DELETE /recipes/1 # DELETE /recipes/1.json def destroy @recipe.destroy respond_to do |format| format.html { redirect_to recipes_url, notice: 'Recipe was successfully destroyed.' } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_recipe @recipe = Recipe.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def recipe_params params.require(:recipe).permit(:tittle, :instructions) end end
當Rails應用程式的用戶選擇一個操作時,例如「Show」,控制器將執行相應部分中的任何代碼-「def Show」,然後默認情況下將呈現一個同名的模板-「Show.html.erb」。可以覆蓋此默認行爲。
控制器使用ActiveRecord方法,例如find、find_all、new、save、update_attributes和destroy在資料庫表之間移動數據。注意,您不必編寫任何SQL語句,rails會自動處理它。
這一行代碼將激活資料庫表。它將爲您的數據提供一個簡單的接口,並提供-minus;
- Creating new entries
- Editing current entries
- Viewing current entries
- Destroying current entries
在創建或編輯條目時,scaffold將爲您完成所有的艱苦工作,如表單生成和處理,甚至將提供聰明的表單生成,支持以下類型的輸入−
- Simple text strings
- Text areas (or large blocks of text)
- Date selectors
- Date-time selectors
您可以使用Rails遷移來創建和維護表。
rake db:migrate RAILS_ENV=development
現在,轉到cookbook目錄並使用以下命令運行Web伺服器−
cookbook> rails server
現在,打開瀏覽器並導航到http://127.0.0.1:3000/recipe/new。這將爲您提供一個在recipes表中創建新條目的螢幕。螢幕截圖如下所示;
一旦您按下創建按鈕來創建一個新的配方,您的記錄將被添加到配方表中,並顯示以下結果−
您可以看到編輯、顯示和銷毀記錄的選項。所以,在這些選項上遊刃有餘。
還可以使用URL http://127.0.0.1:3000/recipe/list列出recipes表中可用的所有配方。
Enhancing the Model
Rails免費爲您提供很多錯誤處理。要理解這一點,請在空配方模型中添加一些驗證規則−
修改app/models/recipe.rb如下,然後測試您的應用程式&負;
class Recipe < ActiveRecord::Base validates_length_of :title, :within => 1..20 validates_uniqueness_of :title, :message => "already exists" end
這些條目將進行自動檢查。
驗證−的長度,該欄位不爲空且不太長。
驗證−重複值的唯一性是否被捕獲。我們在這裡提供了一個自定義消息,而不是默認的Rails錯誤消息。
Alternative Way to Create Scaffolding
如上圖所示創建一個應用程式,生成的Scaffold代碼如下所示
rails g scaffold Recipe tittle:string instructions:text
上面的代碼使用帶有標題和指令列的sqlite3生成帶有資料庫的自動文件,如下圖所示。
我們需要使用下面的語法遷移資料庫。
$ rake db:migrate RAILS_ENV=development
最後使用以下命令行運行應用程式−
rails server
它將生成上述輸出圖像所示的結果。
The Views
所有視圖和相應的所有控制器方法都是通過scaffold命令創建的,它們可以在app/views/recipes目錄中找到。
How Scaffolding is Different?
如果您已經閱讀了前面的章節,那麼您一定已經看到我們創建了列表、顯示、刪除和創建數據等方法,但是scaffolding會自動完成這項工作。
Ruby on Rails - AJAX
Ajax代表AsynchronousJavaScript和XML。Ajax不是單一的技術,它是多種技術的組合。Ajax包含以下內容−
- XHTML for the markup of web pages
- CSS for the styling
- Dynamic display and interaction using the DOM
- Data manipulation and interchange using XML
- Data retrieval using XMLHttpRequest
- JavaScript as the glue that meshes all this together
Ajax允許您檢索web頁面的數據,而無需刷新整個頁面的內容。在基本的web架構中,用戶單擊連結或提交表單。表單被提交到伺服器,然後伺服器發送回一個響應。然後在新頁面上爲用戶顯示響應。
當您與Ajax驅動的web頁面交互時,它會在後台加載Ajax引擎。引擎是用JavaScript編寫的,它的職責是與web伺服器通信並向用戶顯示結果。當使用Ajax支持的表單提交數據時,伺服器返回一個HTML片段,其中包含伺服器的響應,並且只顯示新的或更改的數據,而不是刷新整個頁面。
有關AJAX的完整詳細信息,請閱讀我們的AJAX教程
How Rails Implements Ajax
Rails對於如何實現Ajax操作有一個簡單、一致的模型。一旦瀏覽器呈現並顯示了初始web頁面,不同的用戶操作將導致它顯示新的web頁面(與任何傳統web應用程式一樣)或觸發Ajax操作;
某些觸發器觸發−此觸發器可能是用戶單擊按鈕或連結、用戶更改窗體或欄位中的數據,或者只是周期性觸發器(基於計時器)。
web客戶端調用伺服器−一個JavaScript方法XMLHttpRequest,將與觸發器相關的數據發送到伺服器上的操作處理程序。數據可能是複選框的ID、輸入欄位中的文本或整個表單。
伺服器正在處理伺服器端操作處理程序(Rails controller action)對數據執行某些操作,並將HTML片段返回給web客戶端。
客戶機接收響應−由Rails自動創建的客戶機端JavaScript接收HTML片段,並使用它更新當前頁面HTML的指定部分,通常是<div>標記的內容。
這些步驟是在Rails應用程式中使用Ajax的最簡單方法,但是只需做一些額外的工作,您就可以讓伺服器響應Ajax請求返回任何類型的數據,並且可以在瀏覽器中創建自定義JavaScript來執行更複雜的交互。
AJAX Example
本例基於scaffold,Destroy concept基於ajax。
在本例中,我們將提供、列出、顯示和創建對ponies表的操作。如果您不了解scaffold技術,那麼我們建議您先閱讀前面的章節,然後在Rails上繼續使用AJAX。
Creating An Application
讓我們從創建一個應用程式開始,它將按如下方式完成&負;
rails new ponies
上面的命令創建了一個應用程式,現在我們需要使用with cd命令調用app目錄。它將進入應用程式目錄,然後我們需要調用scaffold命令。它將按以下步驟完成&負;
rails generate scaffold Pony name:string profession:string
上面的命令生成帶有name和profession列的scaffold。我們需要按照以下命令遷移資料庫
rake db:migrate
現在按如下命令運行Rails應用程式
rails s
現在打開web瀏覽器並調用一個url作爲http://localhost:3000/ponies/new,輸出如下
Creating an Ajax
現在用合適的文本編輯器打開app/views/ponies/index.html.erb。使用:remote=>true,:class=>'delete\u pony'更新銷毀行。最後,如下所示。
創建一個文件destroy.js.erb,將它放在其他.erb文件旁邊(在app/views/ponies下)。應該是這樣的&負;
現在在destroy.js.erb中輸入如下所示的代碼
$('.delete_pony').bind('ajax:success', function() { $(this).closest('tr').fadeOut(); });
現在打開位於app/controllers/ponies_controller.rb的控制器文件,並在destroy方法中添加以下代碼,如下所示−
# DELETE /ponies/1 # DELETE /ponies/1.json def destroy @pony = Pony.find(params[:id]) @pony.destroy respond_to do |format| format.html { redirect_to ponies_url } format.json { head :no_content } format.js { render :layout => false } end end
最後控制器頁面如圖所示。
現在運行一個應用程式,從http://localhost:3000/ponies/new調用輸出,如下所示
按下create pony按鈕,將產生如下結果
現在點擊後退按鈕,它將顯示所有小馬創建的信息,如圖所示
到目前爲止,我們正在研究scaffold,現在點擊destroy按鈕,它會調用一個彈出窗口,如下圖所示,這個彈出窗口基於Ajax工作。
如果單擊ok按鈕,它將從小馬中刪除記錄。在這裡我點擊了ok按鈕。最終輸出如下所示;
Ruby on Rails - File Uploading
您可能需要網站訪問者在伺服器上上載文件。Rails使得處理這個需求變得非常容易。現在我們將繼續進行一個簡單而小型的Rails項目。
像往常一樣,讓我們從一個名爲testfile的新Rails應用程式開始。讓我們使用simple rails命令創建應用程式的基本結構。
tp> rails new testfile
在開始應用程式開發之前,我們應該安裝gem文件,如下所示−
gem install carrierwave gem install bootstrap-sass
打開gemfile並在底部添加以下兩個gem,如下圖所示;
在gem文件中添加gems之後,我們需要在控制台上運行以下命令−
bundle install
Creating the Model
我們需要創建一個具有兩個字符串作爲名稱和附件的模型,如下所示;
rails g model Resume name:string attachment:string
我們需要創建如下所示的資料庫遷移;
rake db:migrate
我們需要生成如下所示的控制器;
rails g controller Resumes index new create destroy
偉大的!現在我們已經建立了基本結構。現在我們需要創建一個上傳程序。一個上傳程序來自carrierwave gem,它告訴carrierwave如何處理文件。簡而言之,它包含了所有的文件處理功能。運行命令創建上傳程序,如下所示
rails g uploader attachment
現在打開resume模型並調用上傳程序,如下所示。簡歷模型已放置在app/models/Resume.rb−
class Resume < ActiveRecord::Base mount_uploader :attachment, AttachmentUploader # Tells rails to use this uploader for this model. validates :name, presence: true # Make sure the owner's name is present. end
在使用控制器之前,我們需要修改config/routes.db,如下所示−
CarrierWaveExample::Application.routes.draw do resources :resumes, only: [:index, :new, :create, :destroy] root "resumes#index" end
讓我們編輯控制器,如下所示。
class ResumesController < ApplicationController def index @resumes = Resume.all end def new @resume = Resume.new end def create @resume = Resume.new(resume_params) if @resume.save redirect_to resumes_path, notice: "The resume #{@resume.name} has been uploaded." else render "new" end end def destroy @resume = Resume.find(params[:id]) @resume.destroy redirect_to resumes_path, notice: "The resume #{@resume.name} has been deleted." end private def resume_params params.require(:resume).permit(:name, :attachment) end end
讓我們在css文件中添加引導實現。css文件可以在app/assets/stylesheets/resumes.css.scss中
@import "bootstrap";
現在打開app/views/layouts/application.html.erb並添加如下所示的代碼−
<!DOCTYPE html> <html> <head> <title>Tutorialspoint</title> <%= stylesheet_link_tag "application", media: "all", "data-turbolinks-track" => true %> <%= javascript_include_tag "application", "data-turbolinks-track" => true %> <%= csrf_meta_tags %> </head> <body> <div class = "container" style = "padding-top:20px;"> <%= yield %> </div> </body> </html>
現在我們需要設置如下所示的索引視圖;
<% if !flash[:notice].blank? %> <div class = "alert alert-info"> <%= flash[:notice] %> </div> <% end %> <br /> <%= link_to "New Resume", new_resume_path, class: "btn btn-primary" %> <br /> <br /> <table class = "table table-bordered table-striped"> <thead>. <tr> <th>Name</th> <th>Download Link</th> <th> </th> </tr> </thead> <tbody> <% @resumes.each do |resume| %> <tr> <td><%= resume.name %></td> <td><%= link_to "Download Resume", resume.attachment_url %></td> <td><%= button_to "Delete", resume, method: :delete, class: "btn btn-danger", confirm: "Are you sure that you wish to delete #{resume.name}?" %></td> </tr> <% end %> </tbody> </table>
現在,讓我們編輯new.html.erb並添加表單代碼。
<% if !@resume.errors.empty? %> <div class = "alert alert-error"> <ul> <% @resume.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> <div class = "well"> <%= form_for @resume, html: { multipart: true } do |f| %> <%= f.label :name %> <%= f.text_field :name %> <%= f.label :attachment %> <%= f.file_field :attachment %> <%= f.submit "Save", class: "btn btn-primary" %> <% end %> </div>
現在啓動伺服器並訪問http://localhost:3000。它將產生一個類似於如下的螢幕&負;
我們需要做的最後一件事是過濾允許的文件類型列表。爲此,我們需要在app/uploaders/attachment_uploader.rb添加如下所示的簡單代碼
class AttachmentUploader < CarrierWave::Uploader::Base storage :file def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end def extension_white_list %w(pdf doc htm html docx) end end
現在啓動伺服器並訪問http://localhost:3000。現在輸入一個錯誤的格式;它將生成一個錯誤的消息,如下所示;
有關文件對象的完整詳細信息,您需要閱讀Ruby參考手冊。
Ruby on Rails - Send Emails
Action Mailer是Rails組件,它允許應用程式發送和接收電子郵件。在本章中,我們將看到如何使用Rails發送電子郵件。讓我們使用下面的命令開始創建一個電子郵件項目。
tp> rails new mailtest
這將創建繼續所需的框架。現在,我們將從配置ActionMailer開始。
Action Mailer - Configuration
以下是在繼續實際工作之前完成配置所必須遵循的步驟;
轉到emails項目的config文件夾,打開environment.rb文件,並在該文件底部添加以下行。
config.action_mailer.delivery_method = :smtp
它告訴ActionMailer您要使用SMTP伺服器。如果您使用的是基於Unix的作業系統(如Mac OS X或Linux),也可以將其設置爲:sendmail。
在environment.rb的底部添加以下代碼行。
config.action_mailer.smtp_settings = { address: 'smtp.gmail.com', port: 587, domain: 'example.com', user_name: '<username>', password: '<password>', authentication: 'plain', enable_starttls_auto: true }
用簡單郵件傳輸協議(SMTP)伺服器的正確設置替換每個哈希值。如果您還不知道,可以從您的Internet服務提供商處獲取此信息。如果使用標準的SMTP伺服器,則不需要更改埠號25和身份驗證類型。
您也可以更改默認電子郵件格式。如果您希望用HTML而不是純文本格式發送電子郵件,請將以下行添加到config/environment.rb以及−
ActionMailer::Base.default_content_type = "text/html"
ActionMailer::Base.default_content_type可以設置爲「text/plain」、「text/html」和「text/enriched」。默認值爲「文本/純文本」。
下一步是創建一個郵件程序
Generate a Mailer
使用以下命令生成郵件程序,如下所示−
tp> cd emails emails> rails generate mailer Usermailer
這將在app\mailer目錄中創建一個文件user\mailer.rb。檢查此文件的內容,如下所示−
class Emailer < ActionMailer::Base end
讓我們創建一個方法,如下所示−
class UserMailer < ApplicationMailer default from: 'notifications@example.com' def welcome_email(user) @user = user @url = 'http://www.gmail.com' mail(to: @user.email, subject: 'Welcome to My Awesome Site') end end
默認哈希−這是您從此郵件程序發送的任何電子郵件的默認值的哈希。在本例中,我們將:from頭設置爲該類中所有消息的值。這可以在每個電子郵件的基礎上覆蓋
mail−實際的電子郵件,我們將傳入:to和:subject標題。
在app/views/user_mailer/中創建一個名爲welcome_email.html.erb的文件。這將是電子郵件使用的模板,格式爲HTML−
<html> <head> <meta content = 'text/html; charset = UTF-8' http-equiv = 'Content-Type' /> </head> <body> <h1>Welcome to example.com, <%= @user.name %></h1> <p> You have successfully signed up to example.com,your username is: <%= @user.login %>.<br> </p> <p> To login to the site, just follow this link: <%= @url %>. </p> <p>Thanks for joining and have a great day!</p> </body> </html>
接下來,我們將爲這個應用程式創建一個文本部分,如下所示−
Welcome to example.com, <%= @user.name %> =============================================== You have successfully signed up to example.com, your username is: <%= @user.login %>. To login to the site, just follow this link: <%= @url %>. Thanks for joining and have a great day!
Calling the Mailer
首先,讓我們創建一個簡單的用戶腳手架
$ bin/rails generate scaffold user name email login $ bin/rake db:migrate
Action Mailer與Active Job很好地集成在一起,因此您可以在請求-響應周期之外發送電子郵件,因此用戶不必等待它;
class UsersController < ApplicationController # POST /users # POST /users.json def create @user = User.new(params[:user]) respond_to do |format| if @user.save # Tell the UserMailer to send a welcome email after save UserMailer.welcome_email(@user).deliver_later format.html { redirect_to(@user, notice: 'User was successfully created.') } format.json { render json: @user, status: :created, location: @user } else format.html { render action: 'new' } format.json { render json: @user.errors, status: :unprocessable_entity } end end end end
現在,使用http://127.0.0.1:3000/users/new測試您的應用程式。它顯示以下螢幕,通過使用此螢幕,您將能夠向任何人發送您的消息。
這將發送您的消息,並顯示文本消息「message sent successfully」(消息發送成功)並輸出如下−
sent mail to kittuprasad700@gmail.com (2023.Sms) [ActiveJob] [ActionMailler::DeliveryJob] [2cfde3c-260e-4a33-1a6ada13a9b] Date: Thu, 09 Jul 2015 11:44:05 +0530 From: notification@example.com To: kittuprasad700@gmail.com Message-Id: <559e112d63c57_f1031e7f23467@kiranPro.mail> Subject: Welcome to My Awesome Site Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="--mimepart_559e112d601c8_f1031e7f20233f5"; charset=UTF-8 Content-Transfer-Encoding:7bit
有關如何使用Rails發送電子郵件的更多信息,請瀏覽ActionMailer。