Raaaaaails數據庫的進階操作

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來保存
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:stringrails 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

這樣我們就可以模擬多對多關系了,應該比默認的方法查詢速度要快很多吧!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,514評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,743評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,199評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,414評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,951評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,780評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,218評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,673評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容