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

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

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

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

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

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

②一對多關(guān)系
我們使用user表對應(yīng)article表,每個用戶都有很多的文章,但是每篇文章都只對應(yīng)一個用戶
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 返回用戶示例的文章數(shù)量
user.article_ids 返回用戶示例的文章id,以數(shù)組形式返回
user.articles.clear 清空用戶的文章
user.articles.find 傳入文章的id,返回該文章
user.articles.build(attributes={}) 創(chuàng)建一個新的用戶文章對象,不會保存,需要使用user.articles.last.save來保存
user.articles.create(attributes={}) 直接創(chuàng)建文章對象,并且保存到數(shù)據(jù)庫中。

③關(guān)系型數(shù)據(jù)庫擴展
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

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

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

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

#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是一樣的效果,也就是說我們可以使用下面的方式來創(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

下面我們在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"    

多對多關(guān)系需要注意,我們可以為每個字段添加索引,并且可以通過數(shù)據(jù)庫來保證每個字段的唯一性

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

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

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容