Raaaaaails數(shù)據(jù)庫(kù)的進(jìn)階操作

1.在我們的模型中添加下面方法

class Article < ActiveRecord::Base
     validates_presence_of :title
     validates_presence_of :body
 
     def long_title
         "#{title} - #{published_at}"
     end
end

我們就使用上面的方法來(lái)操作數(shù)據(jù)庫(kù)了
#在命令行中操作模型
>> 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.數(shù)據(jù)庫(kù)之間的關(guān)系
①一對(duì)一關(guān)系
首先:我們創(chuàng)建兩張表
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
我們分別在兩個(gè)模型中創(chuàng)建對(duì)應(yīng)的方法

#User模型
class User < ActiveRecord::Base
has_one :profile
end
#Profile模型
class Profile < ActiveRecord::Base
belongs_to :user
end

我們接下來(lái)可以在rails命令行中做測(cè)試了

>> 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">

一對(duì)一模型中常用方法總結(jié)如下:
user.profile 返回user對(duì)應(yīng)的profile對(duì)象
user.profile=(profile)對(duì)user的profile賦值
user.profile.nil? 返回user的profile是否為空,為空返回真
user.build_profile(attributes={}) 返回一條新的user的profile對(duì)象,但是不會(huì)保存到數(shù)據(jù)庫(kù)老客,需要使用user.profile.save來(lái)保存
user.create_profile(attributes={})返回user的profile對(duì)象逢唤,直接保存到數(shù)據(jù)庫(kù)中

②一對(duì)多關(guān)系
我們使用user表對(duì)應(yīng)article表治笨,每個(gè)用戶(hù)都有很多的文章到千,但是每篇文章都只對(duì)應(yīng)一個(gè)用戶(hù)
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#每篇文章指定屬于用戶(hù)
    def long_title
        "#{title} - #{published_at}"
    end
end
#用戶(hù)表   
class User < ActiveRecord::Base
    has_one :profile
    has_many :articles
end

我們?cè)趓ails命令 行中使用示例
>> 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">

一對(duì)多常用方法
user.articles 返回用戶(hù)模型中所有文章對(duì)象
user.articles=(articles) 替換用戶(hù)模型的所有文章對(duì)象昆码,用articles來(lái)代替
user.articles << article 添加article對(duì)象到user的文章對(duì)象中
user.articles.delete(articles) 刪除文章模型中的一篇或者多篇文章
user.articles.empty? 判斷用戶(hù)實(shí)例的文章是否是空的
user.articles.size 返回用戶(hù)示例的文章數(shù)量
user.article_ids 返回用戶(hù)示例的文章id憨琳,以數(shù)組形式返回
user.articles.clear 清空用戶(hù)的文章
user.articles.find 傳入文章的id物咳,返回該文章
user.articles.build(attributes={}) 創(chuàng)建一個(gè)新的用戶(hù)文章對(duì)象锣险,不會(huì)保存,需要使用user.articles.last.save來(lái)保存
user.articles.create(attributes={}) 直接創(chuàng)建文章對(duì)象览闰,并且保存到數(shù)據(jù)庫(kù)中芯肤。

③關(guān)系型數(shù)據(jù)庫(kù)擴(kuò)展
i.定義默認(rèn)排序

#指定單個(gè)的排序
class User < ActiveRecord::Base
    has_one :profile
    has_many :articles, -> { order('published_at DESC') }
end

#指定多個(gè)字段排序
class User < ActiveRecord::Base
    has_one :profile
    has_many :articles, -> { order('published_at DESC, title ASC')}
end

ii.特殊依賴(lài)
當(dāng)我們刪除一個(gè)用戶(hù)時(shí),該用戶(hù)的所有文章都會(huì)被刪除

class User < ActiveRecord::Base
    has_one :profile
    has_many :articles, -> { order('published_at DESC, title ASC')}, :dependent => :destroy
end

當(dāng)然我們也可以不刪除文章压鉴,可以設(shè)置被刪除用戶(hù)的所有文章的user_id為空

class User < ActiveRecord::Base
    has_one :profile
    has_many :articles, -> { order('published_at DESC, title ASC')}, :dependent => :nullify
end

④多對(duì)多關(guān)系
我們假定一篇文章有很多種分類(lèi)崖咨,一個(gè)分類(lèi)也有很多文章,我們使用rails generate model Category name:stringrails generate migration create_articles_categories分別創(chuàng)建分類(lèi)表和中間表油吭,中間表的定義如下

#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是一樣的效果击蹲,也就是說(shuō)我們可以使用下面的方式來(lái)創(chuàng)建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

下面我們?cè)趓ails命令行中測(cè)試,

>> 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"    

多對(duì)多關(guān)系需要注意婉宰,我們可以為每個(gè)字段添加索引歌豺,并且可以通過(guò)數(shù)據(jù)庫(kù)來(lái)保證每個(gè)字段的唯一性

add_index :articles_categories, :article_id
add_index :articles_categories, :category_id
add_index :articles_categories, [:article_id, :category_id], unique: true
自定義方法來(lái)模擬多對(duì)多關(guān)系

還是通過(guò)文章和分類(lèi)模型來(lái)定義多對(duì)多關(guān)系
1.創(chuàng)建ac數(shù)據(jù)庫(kù)

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.分別在文章和分類(lèi)模型中定義下面的方法

class Article < ActiveRecord::Base
validates_presence_of :title
validates_presence_of :body

belongs_to :user
has_many :acs, dependent: :destroy #這里我們不需要制定外鍵,默認(rèn)是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#這里我們不需要制定外鍵芍阎,默認(rèn)是category_id

def alla
    articles = []
    self.acs.each {|i| articles << Article.find(i.article_id)}
    return articles
end

end
最后在ac類(lèi)中定義下面的方法

class Ac < ActiveRecord::Base
belongs_to :article, class_name: "Article"
belongs_to :category, class_name: "Category"
end

這樣我們就可以模擬多對(duì)多關(guān)系了世曾,應(yīng)該比默認(rèn)的方法查詢(xún)速度要快很多吧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谴咸,一起剝皮案震驚了整個(gè)濱河市轮听,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岭佳,老刑警劉巖血巍,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異珊随,居然都是意外死亡述寡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)叶洞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鲫凶,“玉大人,你說(shuō)我怎么就攤上這事衩辟∶牛” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵艺晴,是天一觀(guān)的道長(zhǎng)昼钻。 經(jīng)常有香客問(wèn)我掸屡,道長(zhǎng),這世上最難降的妖魔是什么然评? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任仅财,我火速辦了婚禮,結(jié)果婚禮上碗淌,老公的妹妹穿的比我還像新娘盏求。我一直安慰自己,他們只是感情好贯莺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布风喇。 她就那樣靜靜地躺著,像睡著了一般缕探。 火紅的嫁衣襯著肌膚如雪魂莫。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,741評(píng)論 1 289
  • 那天爹耗,我揣著相機(jī)與錄音耙考,去河邊找鬼。 笑死潭兽,一個(gè)胖子當(dāng)著我的面吹牛倦始,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播山卦,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼鞋邑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了账蓉?” 一聲冷哼從身側(cè)響起枚碗,我...
    開(kāi)封第一講書(shū)人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铸本,沒(méi)想到半個(gè)月后肮雨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡箱玷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年怨规,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锡足。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡波丰,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出舶得,到底是詐尸還是另有隱情掰烟,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站媚赖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏珠插。R本人自食惡果不足惜惧磺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捻撑。 院中可真熱鬧磨隘,春花似錦、人聲如沸顾患。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)江解。三九已至设预,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間犁河,已是汗流浹背鳖枕。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留桨螺,地道東北人宾符。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像灭翔,于是被迫代替她去往敵國(guó)和親魏烫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理肝箱,服務(wù)發(fā)現(xiàn)哄褒,斷路器,智...
    卡卡羅2017閱讀 134,628評(píng)論 18 139
  • # 一度蜜v3.0協(xié)議 --- # 交互協(xié)議 [TOC] ## 協(xié)議說(shuō)明 ### 請(qǐng)求參數(shù) 下表列出了v3.0版協(xié)...
    c5e350bc5b40閱讀 641評(píng)論 0 0
  • //我所經(jīng)歷的大數(shù)據(jù)平臺(tái)發(fā)展史(三):互聯(lián)網(wǎng)時(shí)代 ? 上篇http://www.infoq.com/cn/arti...
    葡萄喃喃囈語(yǔ)閱讀 51,191評(píng)論 10 200
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,734評(píng)論 25 707
  • 至今聽(tīng)到對(duì)抑郁癥最大的肯定狭园,最好的評(píng)價(jià)读处,:裝瘋賣(mài)傻 我爸爸說(shuō)給我聽(tīng)的,說(shuō)我的唱矛,這輩子都忘不了罚舱,我想釋?xiě)眩?qǐng)問(wèn)怎么釋?xiě)?/div>
    滌舊閱讀 141評(píng)論 0 0