生成腳手架
手動生成migration,而後每一個字段生成腳手架rails generate scaffold Article title:string location:string excerpt:string body:text published_at:datetime --skip-migration
sql
1.生成新的記錄
①使用new構造函數數據庫
>> article = Article.new => #<Article id: nil, title: nil, body: nil, published_at: nil, created_at: nil, updated_at: nil, excerpt: nil, location: nil> >> article.new_record? => true >> article.attributes => {"body"=>nil, "created_at"=>nil, "excerpt"=>nil, "location"=>nil, "published_at"=>nil, "title"=>nil, "updated_at"=>nil} >> article.title = 'RailsConf' => "RailsConf" >> article.body = 'RailsConf is the official gathering for Rails developers..' => "'RailsConf is the official gathering for Rails developers.." >> article.published_at = '2013-04-13' => "2013-04-13" >> article => #<Article id: nil, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2013-04-13 00:00:00", created_at: nil, updated_at: nil, excerpt: nil, location: nil> >> article.save (0.1ms) begin transaction SQL (2.2ms) INSERT INTO "articles" ("body", "created_at", "published_at", "title", "updated_at") VALUES (?,?,?,?,?) [["body", "RailsConf is the official gathering for Rails developers.."], ["created_at", Sat, 13 Apr 2013 15:50:29 UTC +00:00], ["published_at", Wed, 13 Apr 2013 00:00:00 UTC +00:00], ["title", "RailsConf"], ["updated_at", Sat, 13 Apr 2013 15:50:29 UTC +00:00]] (2.9ms) commit transaction => true >> Article.count => 1 >> article.new_record? => false >> article = Article.new >> article.title = "Introduction to SQL" >> article.body = "SQL stands for Structured Query Language, .." >> article.published_at = Date.today >> article.save >> article = Article.new(:title => "Introduction to Active Record", :body => "Active Record is Rails's default ORM..", :published_at => Date.today) >> article.save
②使用create方法數組
>> Article.create(:title => "RubyConf 2013", :body => "The annual RubyConf will take place in..", :published_at => '2013-04-13') => #<Article id: 4, title: "RubyConf 2013", body: "The annual RubyConf will take place in..", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:17:19", updated_at: "2013-04-13 23:17:19", excerpt: nil, location: nil> >> attributes = { :title => "Rails Pub Nite", :body => "Rails Pub Nite is every 3rd Monday of each month, except in December.", :published_at => "2013-04-13"} => {:title=>"Rails Pub Nite", :body=>"Rails Pub Nite is every 3rd Monday of each month, except in December.", :published_at=>" 2013-04-13"} >> Article.create(attributes) => #<Article id: 5, title: "Rails Pub Nite", body: "Rails Pub Nite is every 3rd Monday of each month, e...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:36:07", updated_at: "2013-04-13 23:36:07", excerpt: nil, location: nil> >> Article.count => 5
③使用id查詢單條記錄函數
>> Article.find(3) => #<Article id: 3, title: "Introduction to Active Record", body: "Active Record is Rails's default ORM..", published_at: "2013-04-13 04:00:00", created_at: "2013-04-13 23:15:37", updated_at: "2013-04-13 23:15:37", excerpt: nil, location: nil> >>article = Article.find(3) =>#<Article id: 3 ...> >>article.id =>3 >>article.title =>"Introduction to Active Record"
④使用first和last查詢單條記錄測試
>> Article.first => #<Article id: 1, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:12:09", updated_at: "2010-04-13 23:12:09", excerpt: nil, location: nil> >> Article.last => #<Article id: 5, title: "Rails Pub Nite", body: "Rails Pub Nite is every 3rd Monday of each month, e...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:36:07", updated_at: "2013-04-13 23:36:07", excerpt: nil, location: nil>
⑤查詢多條記錄ui
>> articles = Article.all => [#<Article id: 1,..> #<Article id: 2,..>, #<Article id: 3,..>, #<Article id: 4,..> , #<Article id: 5,..>] >> articles.class => Array >> articles.size => 5 >> articles[0] => #<Article id: 1, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:12:09", updated_at: "2013-04-13 23:12:09", excerpt: nil, location: nil> >> articles[0].title => "RailsConf" >> articles.first.title => "RailsConf" >> articles.each { |article| puts article.title } RailsConf Introduction to SQL Introduction to Active Record RubyConf 2010 Rails Pub Nite => [#<Article id: 1,..> #<Article id: 2,..>, #<Article id: 3,..>, #<Article id: 4,..> , #<Article id: 5,..>]
⑥使用order對數據進行排序
默認是降序,咱們可使用DESC改變爲升序命令行
>> articles = Article.order("published_at") => [#<Article id: 1,..> #<Article id: 2,..>, #<Article id: 3,..>, #<Article id: 4,..> , #<Article id: 5,..>] >> articles.each {|article| puts article.published_at }2013-04-13 00:00:00 UTC2013-04-13 04:00:00 UTC2013-04-13 04:00:00 UTC2013-04-13 00:00:00 UTC2013-04-13 00:00:00 UTC => [#<Article id: 1,..> #<Article id: 2,..>, #<Article id: 3,..>, #<Article id: 4,..> , #<Article id: 5,..>] >> articles = Article.order ('published_at DESC') => [#<Article id: 4,..> #<Article id: 5,..>, #<Article id: 2,..>, #<Article id: 3,..> , #<Article id: 1,..>] >> articles.each {|article| puts article.published_at }2013-04-13 00:00:00 UTC2013-04-13 00:00:00 UTC2013-04-13 00:00:00 UTC2013-04-13 00:00:00 UTC2013-04-13 00:00:00 UTC => [#<Article id: 4,..> #<Article id: 5,..>, #<Article id: 2,..>, #<Article id: 3,..> , #<Article id: 1,..>]
⑦條件查詢代理
>> Article.where(:title => 'RailsConf').first => #<Article id: 1, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:12:09", updated_at: "2013-04-13 23:12:09", excerpt: nil, location: nil> >> Article.where(:title => 'RailsConf').all => [#<Article id: 1, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:12:09", updated_at: "2013-04-13 23:12:09", excerpt: nil, location: nil>] >> Article.where(:title => 'Unknown').all => []
⑧更新記錄code
>> article = Article.first >> article.title = "Rails 4 is great" >> article.published_at = Time.now >> article.save => true
也能夠一次性更新多個字段orm
>> article = Article.first >> article.update_attributes(:title => "RailsConf2013", :published_at => 1.day.ago) => true
或者更新一個字段
>> article = Article.first >> article.update_attribute(:title => "RailsConf2013") => true
⑨刪除記錄
>> article = Article.last >> article.destroy => #<Article id: 5, title: "Rails Pub Nite", body: "Rails Pub Nite is every 3rd Monday of each month, e...", published_at: "2013-04-13 00:00:00", created_at: "2013-04-13 23:36:07", updated_at: "2013-04-13 23:36:07", excerpt: nil, location: nil> #或者在一行裏面操做 >> Article.last.destroy >> Article.destroy(1) => [#<Article id: 1, title: "RailsConf", body: "RailsConf is the official gathering for Rails devel...", published_at: "2010-02-27 00:00:00", created_at: "2010-05-01 23:12:09", updated_at: "2010-05-01 23:12:09", excerpt: nil, location: nil>] #刪除多條記錄 >> Article.destroy([2,3]) => [#<Article id: 2, ..>, #<Article id: 3, ..>]
使用destroy是沒有返回值的,若是須要返回值,咱們可使用delete方法來刪除記錄
>> Article.delete(4) => 1 #數據庫中不存在5到6的記錄,因此返回0 >> Article.delete([5, 6]) => 0
規定條件刪除相應的記錄
>> Article.delete_all("published_at < '2011-01-01'") >> 0
1.在咱們的模型中添加下面方法
class Article < ActiveRecord::Base validates_presence_of :title validates_presence_of :body def long_title "#{title} - #{published_at}" end end
咱們就使用上面的方法來操做數據庫了
#在命令行中操做模型 >> Article.create :title => 'Advanced Active Record', :published_at => Date.today, :body => 'Models need to relate to each other. In the real world, ...' => #<Article id: 6, title: "Advanced Active Record", ...> >> Article.last.long_title => "Advanced Active Record - 2013-04-22 04:00:00 UTC"
2.數據庫之間的關係
①一對一關係
首先:咱們建立兩張表rails generate model User email:string password:string
rails generate model Profile user_id:integer name:string birthday:date bio:text color:string twitter:string
咱們分別在兩個模型中建立對應的方法
#User模型 class User < ActiveRecord::Base has_one :profile end #Profile模型 class Profile < ActiveRecord::Base belongs_to :user end
咱們接下來能夠在rails命令行中作測試了
>> user = User.create(:email => 'user@example.com', :password => 'secret') => #<User id: 1, email: "user@example.com", password: "secret", created_at: "2013-04-02 15:10:07", updated_at: "2013-04-02 15:10:07"> >> profile = Profile.create(:name => 'John Doe', :bio => 'Ruby developer trying to learn Rails') => #<Profile id: 1, user_id: nil, name: "John Doe", birthday: nil, bio: "Ruby developer trying to learn Rails", color: nil, twitter: nil, created_at: "2013-04-02 15:10:55", updated_at: "2013-04-02 15:10:55"> >> user.profile => nil >> user.profile = profile => #<Profile id: 1, user_id: 1, name: "John Doe", birthday: nil, bio: "Ruby developer trying to learn Rails", color: nil, twitter: nil, created_at: "2013-04-02 15:10:55", updated_at: "2013-04-02 15:10:55"> >> user.profile => #<Profile id: 1, user_id: 1, name: "John Doe", birthday: nil, bio: "Ruby developer trying to learn Rails", color: nil, twitter: nil, created_at: "2013-04-02 15:10:55", updated_at: "2013-04-02 15:10:55"> >> user.create_profile :name => 'Jane Doe', :color => 'pink' => #<Profile id: 2, user_id: 1, name: "Jane Doe", birthday: nil, bio: nil, color: "pink", twitter: nil, created_at: "2013-04-02 15:18:57", updated_at: "2013-04-02 15:18:57">
一對一模型中經常使用方法總結以下:user.profile
返回user對應的profile對象user.profile=(profile)
對user的profile賦值user.profile.nil?
返回user的profile是否爲空,爲空返回真user.build_profile(attributes={})
返回一條新的user的profile對象,可是不會保存到數據庫,須要使用user.profile.save
來保存user.create_profile(attributes={})
返回user的profile對象,直接保存到數據庫中
②一對多關係
咱們使用user表對應article表,每一個用戶都有不少的文章,可是每篇文章都只對應一個用戶rails generate migration add_user_id_to_articles user_id:integer
#文章表模型 class Article < ActiveRecord::Base validates_presence_of :title validates_presence_of :body belongs_to :user#每篇文章指定屬於用戶 def long_title "#{title} - #{published_at}" end end #用戶表 class User < ActiveRecord::Base has_one :profile has_many :articles end
咱們在rails命令 行中使用示例
>> user = User.first => #<User id: 1, email: "user@example.com", password: "secret", created_at: "2013-04-02 15:10:07", updated_at: "2013-04-02 15:10:07"> >> user.articles => [] >> user.articles << Article.first => [#<Article id: 6, ..., user_id: 1>] >> user.articles.size => 1 >> user.articles => [#<Article id: 6, ..., user_id: 1>] >> Article.first.user_id => 1 >> Article.first.user => #<User id: 1, email: "user@example.com", password: "secret", created_at: "2013-04-02 15:10:07", updated_at: "2013-04-02 15:10:07">
一對多經常使用方法user.articles
返回用戶模型中全部文章對象user.articles=(articles)
替換用戶模型的全部文章對象,用articles來代替user.articles << article
添加article對象到user的文章對象中user.articles.delete(articles)
刪除文章模型中的一篇或者多篇文章user.articles.empty?
判斷用戶實例的文章是不是空的user.articles.size
返回用戶示例的文章數量user.article_ids
返回用戶示例的文章id,以數組形式返回user.articles.clear
清空用戶的文章user.articles.find
傳入文章的id,返回該文章user.articles.build(attributes={})
建立一個新的用戶文章對象,不會保存,須要使用user.articles.last.save
來保存
PS:這種方法通常在實際的應用是這樣子使用的
product = Product.find(params[:product_id]) @line_item = @cart.line_items.build(product: prodcut)#將產品實例直接傳進來 respond_to do |format| if @line_item.save#使用它來保存
user.articles.create(attributes={})
直接建立文章對象,而且保存到數據庫中。
③關係型數據庫擴展
i.定義默認排序
#指定單個的排序 class User < ActiveRecord::Base has_one :profile has_many :articles, -> { order('published_at DESC') } end #指定多個字段排序 class User < ActiveRecord::Base has_one :profile has_many :articles, -> { order('published_at DESC, title ASC')} end
ii.特殊依賴
當咱們刪除一個用戶時,該用戶的全部文章都會被刪除
class User < ActiveRecord::Base has_one :profile has_many :articles, -> { order('published_at DESC, title ASC')}, :dependent => :destroy end
固然咱們也能夠不刪除文章,能夠設置被刪除用戶的全部文章的user_id爲空
class User < ActiveRecord::Base has_one :profile has_many :articles, -> { order('published_at DESC, title ASC')}, :dependent => :nullify end
④多對多關係
咱們假定一篇文章有不少種分類,一個分類也有不少文章,咱們使用rails generate model Category name:string
和rails generate migration create_articles_categories
分別建立分類表和中間表,中間表的定義以下
#The db/migrate/20130407002156_create_articles_categories.rb: File class CreateArticlesCategories < ActiveRecord::Migration def change create_table :articles_categories, :id => false do |t| t.references :article t.references :category end end def self.down drop_table :articles_categories end end
references
方法和integer
是同樣的效果,也就是說咱們可使用下面的方式來建立add_column :articles_categories, :article_id, :integer
,add_column :articles_categories, :category_id, :integer
下面咱們分別爲Article模型和Category模型添加has_and_belongs_to_many方法
class Article < ActiveRecord::Base has_and_belongs_to_many :categories end class Category < ActiveRecord::Base has_and_belongs_to_many :articles end
下面咱們在rails命令行中測試,
>> article = Article.last => #<Article id: 8, title: "Associations", ...> >> category = Category.find_by_name('Programming') => #<Category id: 1, name: "Programming", ..> >> article.categories << category => [#<Category id: 1, name: "Programming", ..>] >> article.categories.any? => true >> article.categories.size => 1 >> category.articles.empty? => false >> category.articles.size => 1 >> category.articles.first.title >> "Associations"
多對多關係須要注意,咱們能夠爲每一個字段添加索引,增長數據庫的查詢速度,而且能夠經過數據庫來保證每一個字段的惟一性
add_index :articles_categories, :article_id add_index :articles_categories, :category_id add_index :articles_categories, [:article_id, :category_id], unique: true
仍是經過文章和分類模型來定義多對多關係
1.建立ac數據庫
class CreateAcs < ActiveRecord::Migration def change create_table :acs do |t| t.integer :article_id t.integer :category_id t.timestamps end end end
2.分別在文章和分類模型中定義下面的方法
文章模型
class Article < ActiveRecord::Base validates_presence_of :title validates_presence_of :body belongs_to :user has_many :acs, dependent: :destroy #這裏咱們不須要制定外鍵,默認是article_id def long_title "#{title} -- #{published_at}" end def allc categories = [] self.acs.each {|i| categories << Category.find(i.category_id)} return categories end end
分類模型
class Category < ActiveRecord::Base has_many :acs, dependent: :destroy#這裏咱們不須要制定外鍵,默認是category_id def alla articles = [] self.acs.each {|i| articles << Article.find(i.article_id)} return articles end end
最後在ac類中定義下面的方法
class Ac < ActiveRecord::Base belongs_to :article, class_name: "Article" belongs_to :category, class_name: "Category" end
這樣咱們就能夠模擬多對多關係了,應該比默認的方法查詢速度要快不少吧!
>> Aricle.where(:title => 'Advanced Active Record') => [#<Article id: 6, title: "Advanced Active Record", ...>]
>> Article.where("created_at > '23-04-2013' OR body NOT LIKE '%model%'") => [#<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>] >> Article.where("created_at > '23-04-2013' AND body NOT LIKE '%model%'") => []
>> Article.where("published_at < ?", Time.now) => [#<Article id: 6, title: "Advanced Active Record", ...>] >> Article.where("published_at < ?", Time.now).to_sql => "SELECT \"articles\".* FROM \"articles\" WHERE (published_at < '2013-04-02 16:27:51.059277')" >> Article.where("created_at = ?", Article.last.created_at) => [#<Article id: 8, title: "Associations", ...>] >> Article.where("created_at = ? OR body LIKE ?", Article.last.created_at, 'model') => [#<Article id: 8, title: "Associations", ...>] >> Article.where("title LIKE :search OR body LIKE :search", {:search => '%association%'}) => [#<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>]
>> User.first.articles.all => [#<Article id: 8, title: "Associations", ...>] current_user.articles.create(:title => 'Private', :body => ‘Body here..’)
>> Article.all => [#<Article id: 6, title: "Advanced Active Record", ...>, #<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>] >> Article.order("title ASC") => [#<Article id: 6, title: "Advanced Active Record", ...>, #<Article id: 8, title: "Associations", ...>, #<Article id: 7, title: "One-to-many associations", ...>] >> Article.limit(1) => [#<Article id: 6, title: "Advanced Active Record", ...>] >> Article.order("title DESC").limit(2) => [#<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>] >> Article.all => [#<Article id: 6, title: "Advanced Active Record", ...>, #<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>] >> Article.order("title ASC") => [#<Article id: 6, title: "Advanced Active Record", ...>, #<Article id: 8, title: "Associations", ...>, #<Article id: 7, title: "One-to-many associations", ...>] >> Article.limit(1) => [#<Article id: 6, title: "Advanced Active Record", ...>] >> Article.order("title DESC").limit(2) => [#<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>]
首先咱們看看數據庫的默認排序方法
>> Category.all => [#<Category id: 1, name: "Programming", ...>, #<Category id: 2, name: "Event", ...>, #<Category id: 3, name: "Travel", ...>, #<Category id: 4, name: "Music", ..>, #<Category id: 5, name: "TV", ...>]
在category模型中咱們添加default_scope
方法,之後的查詢結構默認會以分類名排序。
class Category < ActiveRecord::Base has_and_belongs_to_many :articles default_scope lambda { order('categories.name') } end
咱們在rails命令行中進行測試
>> reload! Reloading... >> Category.all => [#<Category id: 2, name: "Event", ...>, #<Category id: 4, name: "Music", ...>, #<Category id: 1, name: "Programming", ...>, #<Category id: 5, name: "TV", ...>, #<Category id: 3, name: "Travel", ...>]
首先咱們須要在模型中定義方法,以下
class Article < ActiveRecord::Base scope :published, lambda { where("articles.published_at IS NOT NULL") } scope :draft, lambda { where("articles.published_at IS NULL") } scope :recent, lambda { published.where("articles.published_at > ?", 1.week.ago.to_date)} scope :where_title, lambda { |term| where("articles.title LIKE ?", "%#{term}%") } def long_title "#{title} - #{published_at}" end end
咱們在命令行中測試
>> Article.published => [#<Article id: 6, title: "Advanced Active Record", ...>] >> Article.draft => [#<Article id: 7, title: "One-to-many associations", ...>, #<Article id: 8, title: "Associations", ...>] >> Article.recent => [#<Article id: 6, title: "Advanced Active Record", ...>] >> Article.draft.where_title("one") => [#<Article id: 7, title: "One-to-many associations", ...>] >> Article.where_title("Active") => [#<Article id: 6, title: "Advanced Active Record", ...>]