Mongoid學(xué)習(xí)

1. 安裝mongoid

在Rails 配置文件Gemfile中,做如下配置


  gem 'mongoid', '~> 5.0.0'

2. 配置文件

執(zhí)行 rails g mongoid:config 即可生成
myapp/config/mongoid.yml

在該配置文件中,你可以定制自己的配置


development:
 clients:
   default:
     database: mongoid
     hosts:
       - localhost:27017

還需要在 application.rb 文件中做如下配置,設(shè)置關(guān)系映射使用mongoid


  config.generators do |g|
    g.orm :mongoid
  end

3. Document

Document可以作為集合存儲(chǔ),也可以鑲嵌到其他的Document中

Documents can be stored in their own collections in the database
or can be embedded in other Documents n levels deep.

4. 存儲(chǔ)


  class Person
    include Mongoid::Document
  end

你可以在類級(jí)別更改該P(yáng)erson的存儲(chǔ)位置


  class Person
    include Mongoid::Document
    store_in collection: "citizens", database: "other", client: "secondary"
  end

5. Fields

通過網(wǎng)絡(luò)傳輸?shù)腟tring 參數(shù),
Mongoid 提供了一個(gè)簡(jiǎn)單的機(jī)制來將他們轉(zhuǎn)換成正確合適的類型,
通過定field定義


  class Person
    include Mongoid::Document
    field :first_name, type: String
    field :middle_name, type: String
    field :last_name, type: String
  end

除了String, 還有如下類型:


  Array
  BigDecimal
  Boolean
  Date
  DateTime
  Float
  Hash
  Integer
  BSON::ObjectId
  BSON::Binary
  Range
  Regexp
  String
  Symbol
  Time
  TimeWithZone

6. 訪問設(shè)置Field

如果field已經(jīng)定義,Mongoid提供了多種方式來訪問field


  # Get the value of the first_name field
  person.first_name
  person[:first_name]
  person.read_attribute(:first_name)


  # Set the value for the first_name field
  person.first_name = "Jean"
  person[:first_name] = "Jean"
  person.write_attribute(:first_name, "Jean")

通過以下途徑訪問設(shè)置多值


  # Get the field values as a hash.
  person.attributes

  # Set the field values in the document.
  Person.new(first_name: "Jean-Baptiste", middle_name: "Emmanuel")
  person.attributes = { first_name: "Jean-Baptiste", middle_name: "Emmanuel" }
  person.write_attributes(
    first_name: "Jean-Baptiste",
    middle_name: "Emmanuel"
  )


存儲(chǔ)設(shè)置Hash Field


class Person
  include Mongoid::Document
  field :first_name
  field :url, type: Hash

  # will update the fields properly and save the values
  def set_vals
    self.first_name = 'Daniel'
    self.url = {'home_page' => 'http://www.homepage.com'}
    save
  end

end

存儲(chǔ)到數(shù)據(jù)庫(kù)具體形式如下:


  { "_id" : ObjectId("56877d3408d67e50cb000008"),  "first_name" : "zhangsan", "url" : { "home_page" : "http://www.homepage.com" }, "updated_at" : ISODate("2016-01-02T07:33:34.721Z"), "created_at" : ISODate("2016-01-02T07:33:34.721Z") }

7. 設(shè)置默認(rèn)值


  class Person
    include Mongoid::Document
    field :blood_alcohol_level, type: Float, default: 0.40
    field :last_drink, type: Time, default: ->{ 10.minutes.ago }
  end

或者根據(jù)Object的狀態(tài)來設(shè)置默認(rèn)值


  field :intoxicated_at, type: Time, default: ->{ new_record? ? 2.hours.ago : Time.now }

8. Custom Ids

如果你不想使用BSON::ObjectID ids, 你可以覆蓋 Mongoid`s _id
值,只要你喜歡樂意。


  class Band
    include Mongoid::Document
    field :name, type: String
    field :_id, type: String, default: ->{ name }
  end

9. Dynamic Fields

默認(rèn)情況Mongoid 不支持 dynamic fields,
你可以告訴mongoid支持dynamic fields 通過配置


 including Mongoid::Attributes::Dynamic in model


  class Person
    include Mongoid::Document
    include Mongoid::Attributes::Dynamic
  end

關(guān)于dynamic fields 有兩個(gè)重要的規(guī)則

  1. 如果attribute 在document中存在,Mongoid 提供標(biāo)準(zhǔn)的getter 和 setter

  # Set the person's gender to male.
  person[:gender] = "Male"
  person.gender = "Male"

  # Get the person's gender.
  person.gender

  1. 如果attribute 在document中不存在,Mongoid不提供 getter 和
    setter,并且會(huì)強(qiáng)制拋出異常。在這種情況下,你可以使用
    [] 或 []= 或 read_attribute 或 write_attribute 方法

  >> bb = Teacher.new
  => #<Teacher _id: 5688bdb908d67e29cd000004, >
  >> bb[:gender]
  => nil
  >> bb.read_attribute(:gender)
  => nil
  >> bb[:gender] = "Male"
  => "Male"
  >> bb.write_attribute(:gender, "Female")
  => "Female"
  >> bb[:gender]
  => "Female"
  >> bb.gender
  => "Female"
  >> bb.name
  NoMethodError: undefined method `name' for #<Teacher _id: 5688bdb908d67e29cd000004, gender: "Female">

10. 查看attribute changes變化


  class Person
    include Mongoid::Document
    field :name, type: String
  end

  person = Person.first
  person.name = "Alan Garner"

  # Check to see if the document has changed.
  person.changed? #=> true

  # Get an array of the names of the changed fields.
  person.changed #=> [ :name ]

  # Get a hash of the old and changed values for each field.
  person.changes #=> { "name" => [ "Alan Parsons", "Alan Garner" ] }

  # Check if a specific field has changed.
  person.name_changed? #=> true

  # Get the changes for a specific field.
  person.name_change #=> [ "Alan Parsons", "Alan Garner" ]

  # Get the previous value for a field.
  person.name_was #=> "Alan Parsons"

11. 重置changes


  person = Person.first
  person.name = "Alan Garner"

  # Reset the changed name back to the original
  person.reset_name!
  person.name #=> "Alan Parsons"

12. 關(guān)于changes 和 save的關(guān)系

如果changes沒有任何變更,Mongoid 也不會(huì)變更數(shù)據(jù)庫(kù)的內(nèi)容 通過Model#save
方法


  >> bb = Student.find(BSON::ObjectId("56877eae08d67e50cb00000b"))
  MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"students", "filter"=>{"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b')}}
  MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.010262s
  => #<Student _id: 56877eae08d67e50cb00000b, created_at: 2016-01-02 07:39:26 UTC, updated_at: 2016-01-02 07:43:52 UTC, name: "jean", url: {"home_page"=>"www.jd.com"}, last_drink: 2016-01-02 07:29:26 UTC, intoxicated_at: 2016-01-02 05:39:26 UTC>
  >> bb.attributes
  => {"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b'), "name"=>"jean", "url"=>{"home_page"=>"www.jd.com"}, "last_drink"=>2016-01-02 07:29:26 UTC, "intoxicated_at"=>2016-01-02 05:39:26 UTC, "updated_at"=>2016-01-02 07:43:52 UTC, "created_at"=>2016-01-02 07:39:26 UTC}
  >> bb.updated_at
  => Sat, 02 Jan 2016 07:43:52 UTC +00:00
  >> bb.updated_at.to_s(:db)
  => "2016-01-02 07:43:52"
  >> bb.save
  => true
  >> Student.find(BSON::ObjectId("56877eae08d67e50cb00000b")).updated_at.to_s(:db)
  MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"students", "filter"=>{"_id"=>BSON::ObjectId('56877eae08d67e50cb00000b')}}
  MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.0007s
  => "2016-01-02 07:43:52"

13. Readonly Attributes

你可以設(shè)置某些field為只讀,創(chuàng)建之后便不能修改。


  class Band
    include Mongoid::Document
    field :name, type: String
    field :origin, type: String

    attr_readonly :name, :origin
  end

  band = Band.create(name: "Placebo")
  band.update_attributes(name: "Tool") # Filters out the name change.

如果你強(qiáng)制更新或修改某一個(gè)只讀的field,便會(huì)拋出異常。


  band.update_attribute(:name, "Tool") # Raises the error.
  band.remove_attribute(:name) # Raises the error.

14. 繼承

Document 繼承來自與他們的fields, relations, validations 或者是
scopes 來自于他們的child documents.


  class Canvas
    include Mongoid::Document
    field :name, type: String
    embeds_many :shapes
  end

  class Browser < Canvas
    field :version, type: Integer
    scope :recent, where(:version.gt => 3)
  end

  class Firefox < Browser
  end

  class Shape
    include Mongoid::Document
    field :x, type: Integer
    field :y, type: Integer
    embedded_in :canvas
  end

  class Circle < Shape
    field :radius, type: Float
  end

  class Rectangle < Shape
    field :width, type: Float
    field :height, type: Float
  end

**Querying Subclasses**

  # Returns Canvas documents and subclasses
  Canvas.where(name: "Paper")
  # Returns only Firefox documents
  Firefox.where(name: "Window 1")

**Associations**

```

  firefox = Firefox.new
  # Builds a Shape object
  firefox.shapes.build({ x: 0, y: 0 })
  # Builds a Circle object
  firefox.shapes.build({ x: 0, y: 0 }, Circle)
  # Creates a Rectangle object
  firefox.shapes.create({ x: 0, y: 0 }, Rectangle)

  rect = Rectangle.new(width: 100, height: 200)
  firefox.shapes

```

15. 時(shí)間戳

Mongoid::Timestamps 提供了 created_at 和 updated_at field.


  class Person
    include Mongoid::Document
    include Mongoid::Timestamps
  end

或者你可以使用特殊的時(shí)間戳,creation 或 modification


  class Person
    include Mongoid::Document
    include Mongoid::Timestamps::Created
  end

  class Post
    include Mongoid::Document
    include Mongoid::Timestamps::Updated
  end

16. Persistence

Mongoid supports all expected CRUD operations for those familiar with
other Ruby mappers like Active Record or Data Mapper. What
distinguished Mongoid from other mappers for MongoDB is that the
general persistence operations perform atomic updated on only the
fields that have changed instead of writing the entire document to
the database each time.


Person.create(
first_name: "Heinrich",
last_name: "Heine"
)

Person.create([
{ first_name: "Heinrich", last_name: "Heine" },
{ first_name: "Willy", last_name: "Brandt" }
])

person.save
person.save(validate: false)

person.update_attributes!(
first_name: "Jean",
last_name: "Zorg"
)

person.update_attribute(:first_name, "Jean")


特殊的field用法

Model#upsert

如果這個(gè)attribute 存在,則覆蓋,如果沒有則插入。


  person = Person.new(
    first_name: "Heinrich",
    last_name: "Heine"
  )
  person.upsert

Model#touch

更新updated_at 時(shí)間戳,也可以根據(jù)配置級(jí)聯(lián)更改關(guān)聯(lián)關(guān)系。
該方法跳過validation 和 callbacks


  person.touch
  person.touch(:audited_at)

Model#delete

刪除數(shù)據(jù),并且沒有任何回調(diào)

Model#destory

刪除數(shù)據(jù),并且執(zhí)行回調(diào)

17. Atomic

當(dāng)執(zhí)行這些原子操作時(shí),沒有回調(diào),沒有校驗(yàn)


  person.add_to_set(aliases: "Bond")   # $addToSet
  person.bit(age: { and: 10, or: 12 }) # $bit
  person.inc(age: 1)                   # $inc
  person.pop(aliases: 1)               # $pop
  person.pull(aliases: "Bond")         # $pull

18. 查詢

查詢 DSL


  Band.where(name: "Depeche Mode")
  Band.
    where(:founded.gte => "1980-1-1").
    in(name: [ "Tool", "Deftones" ]).
    union.
    in(name: [ "Melvins" ])

Additional Query Methods

操作 例子
操作 例子
---- ----
Criteria#count
count 查詢會(huì)涉及到數(shù)據(jù)庫(kù)查詢
Band.count
Band.where(name: "Photek").count
Criteria#distinct
獲取單一field
Band.distinct(:name)
Band.where(:fans.gt => 100000).distinct(:name)
Criteria#each
迭代獲取匹配數(shù)據(jù)
Band.where(members: 1).each do
Criteria#exists?
判斷獲取數(shù)據(jù)是否存在
Band.exists?
Band.where(name: "Photek").exists?
Criteria#find
獲取一個(gè)文檔或多個(gè)文檔通過ids,如果沒有找到就會(huì)報(bào)錯(cuò)
Band.find("4baa56f1230048567300485c")
Band.find( "4baa56f1230048567300485c", "4baa56f1230048567300485d")
Criteria#find_by
根據(jù)某一個(gè)field 來獲取文檔
Band.find_by(name: "Photek")
Criteria#find_or_create_by
根據(jù)attributes來查找文檔,如果沒有找到,就創(chuàng)建該文檔
Band.where(:likes.gt => 10).find_or_create_by(name: "Photek")
Criteria#find_or_initialize_by
查找文檔,若沒找到,則初始化
Band.where(:likes.gt => 10).find_or_initialize_by(name: "Photek")
Criteria#first_or_create
根據(jù)attributes 查找第一個(gè)文檔,如果不存在,就創(chuàng)建
Band.where(name: "Photek").first_or_create
Criteria#first_or_initialize
根據(jù)attributes 查找第一個(gè)文檔,如果不存在,就初始化
Band.where(name: "Photek").first_or_initialize
Criteria#pluck
獲取不為nil的值
Band.all.pluck(:name)

19. Eager Loading

Eager loaded is supported on all relations with the exception of polymorphic belongs_to associations.


  class Band
    include Mongoid::Document
    has_many :albums
  end

  class Album
    include Mongoid::Document
    belongs_to :band
  end

  Band.includes(:albums).each do |band|
    p band.albums.first.name # Does not hit the database again.
  end

20. 關(guān)聯(lián)關(guān)系


>> p = Person.find('5687839408d67e50cb00000f')
MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"people", "filter"=>{"_id"=>BSON::ObjectId('5687839408d67e50cb00000f')}}
MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.005945s
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.target
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.base
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses.metadata
=> #<Mongoid::Relations::Metadata
autobuild:    false
class_name:   Address
cyclic:       nil
counter_cache:false
dependent:    nil
inverse_of:   nil
key:          addresses
macro:        embeds_many
name:         addresses
order:        nil
polymorphic:  false
relation:     Mongoid::Relations::Embedded::Many
setter:       addresses=>

21. embeds_many 擴(kuò)展


class Person
  include Mongoid::Document

  field :first_name, type: String
  field :middle_name, type: String
  field :last_name, type: String

  embeds_many :addresses do
    def find_by_name(name)
      where(name: name).first
    end

    def the_one
      @target.select{ |address| address.name == 'one' }
    end
  end
  has_many :posts, autosave: true
end

p.addresses.the_one # return [ address]
p.addresses.find_by_name('aaa') # return address


>> p = Person.find('5687839408d67e50cb00000f')
MONGODB | localhost:27017 | funds_development.find | STARTED | {"find"=>"people", "filter"=>{"_id"=>BSON::ObjectId('5687839408d67e50cb00000f')}}
MONGODB | localhost:27017 | funds_development.find | SUCCEEDED | 0.000462s
=> #<Person _id: 5687839408d67e50cb00000f, first_name: "zhang", middle_name: "san", last_name: "bb">
>> p.addresses
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>, #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>]
>> p.addresses.the_one
=> [#<Address _id: 568783ce08d67e50cb000010, name: "one", addressable_type: nil, addressable_id: nil>]
>> p.addresses.find_by_name('two')
=> #<Address _id: 568783ce08d67e50cb000011, name: "two", addressable_type: nil, addressable_id: nil>

22. 定制關(guān)系的名字

你可以隨意定義關(guān)聯(lián)關(guān)系的名字,但是你需要填寫必要的選項(xiàng)來讓mongoid找到對(duì)應(yīng)
的類。


 class Lush
  include Mongoid::Document
  embeds_one :whiskey, class_name: "Drink", inverse_of: :alcoholic
 end

 class Drink
   include Mongoid::Document
   embedded_in :alcoholic, class_name: "Lush", inverse_of: :whiskey
 end

23. 關(guān)聯(lián)關(guān)系校驗(yàn)

默認(rèn)情況下,如下的關(guān)聯(lián)關(guān)系,會(huì)存在校驗(yàn)。
如果需要去掉關(guān)聯(lián)關(guān)系校驗(yàn),則可以在定義類的時(shí)候,就去除。


  embeds_many
  embeds_one
  has_many
  has_one
  has_and_belongs_to_many


  class Person
    include Mongoid::Document

    embeds_many :addresses, validate: false
    has_many :posts, validate: false
  end

24. embeds_many 與 has_many 的區(qū)別

addresses 屬于 embeds_many
posts 屬于 has_many


  class Person
    include Mongoid::Document

    field :first_name, type: String
    field :middle_name, type: String
    field :last_name, type: String

    embeds_many :addresses do
      def find_by_name(name)
        where(name: name).first
      end

      def the_one
        @target.select{ |address| address.name == 'one' }
      end
    end
    has_many :posts, autosave: true
  end

> db.posts.find()
{ "_id" : ObjectId("5687862c08d67e29cd000001"), "name" : "101", "person_id" : ObjectId("5687839408d67e50cb00000f") }

> db.people.find({ "_id": ObjectId("5687839408d67e50cb00000f") })
{ "_id" : ObjectId("5687839408d67e50cb00000f"), "first_name" : "zhang", "middle_name" : "san", "last_name" : "bb", "addresses" : [ { "_id" : ObjectId("568783ce08d67e50cb000010"), "name" : "one" }, { "_id" : ObjectId("568783ce08d67e50cb000011"), "name" : "two" } ] }

由此可見,embeds_many 是嵌入到其他的document中
而has_many 是額外存在于其他的collections 中

25. 多態(tài)

一個(gè)child document 可以屬于多個(gè)parent document,在parent document
中添加 as 選項(xiàng)來告訴Mongoid, 并且在child document中設(shè)置 polymorphic
選項(xiàng)。在child選項(xiàng)中,根據(jù)這個(gè)額外添加的選項(xiàng),就可以獲取到父類型。

多態(tài)存在于 has_and_belongs_to_many 的關(guān)系中。


  class Band
    include Mongoid::Document
    embeds_many :photos, as: :photographic
    has_one :address, as: :addressable
  end

  class Photo
    include Mongoid::Document
    embedded_in :photographic, polymorphic: true
  end

26. 級(jí)聯(lián)回調(diào)

如果你想在父類上調(diào)用embedded document 的級(jí)聯(lián),需要做如下設(shè)置


  class Band
    include Mongoid::Document
    embeds_many :albums, cascade_callbacks: true
    embeds_one :label, cascade_callbacks: true
  end

  band.save # Fires all save callbacks on the band, albums, and label.

27. 約束行為

如果關(guān)聯(lián)關(guān)系的一方刪除,可以設(shè)置關(guān)聯(lián)的另一方的關(guān)系

:delete: 刪除關(guān)系,不會(huì)調(diào)用什么回調(diào)
:destroy: 刪除關(guān)系,但是會(huì)調(diào)用回調(diào)函數(shù)
:nullify: 使關(guān)聯(lián)關(guān)系的另一方,孤立
:restrict: 如果child不為空,則拋出異常


  class Band
    include Mongoid::Document
    has_many :albums, dependent: :delete
    belongs_to :label, dependent: :nullify
  end

  class Album
    include Mongoid::Document
    belongs_to :band
  end

  class Label
    include Mongoid::Document
    has_many :bands, dependent: :restrict
  end

  label = Label.first
  label.bands.push(Band.first)
  label.delete # Raises an error since bands is not empty.

  Band.first.delete # Will delete all associated albums.


28. 自動(dòng)保存

Mongoid 和 Active Record 的另一個(gè)不同就是,不會(huì)自動(dòng)
保存級(jí)聯(lián)關(guān)系,是為了性能考慮。

鑲嵌的關(guān)聯(lián)并不需要設(shè)置autosave,因?yàn)閷?shí)際上他就是屬于父Object
的一部分。其余的關(guān)聯(lián)關(guān)系,都可以設(shè)置 autosave


  class Band
    include Mongoid::Document
    has_many :albums, autosave: true
  end

  band = Band.first
  band.albums.build(name: "101")
  band.save #=> Will save the album as well.

29. 級(jí)聯(lián)關(guān)系中存在的實(shí)用方法

在所有關(guān)聯(lián)關(guān)系中都存在 name? 和 has_name? 的方法來校驗(yàn)relation
是否是空的


  class Band
    include Mongoid::Document
    embeds_one :label
    embeds_many :albums
  end

  band.label?
  band.has_label?
  band.albums?
  band.has_albums?

30. Embeds One

一對(duì)一的關(guān)聯(lián)關(guān)系中,使用embeds_one 和 embedded_in 來作為屬性關(guān)聯(lián)。


  class Band
    include Mongoid::Document
    embeds_one :label
  end

  class Label
    include Mongoid::Document
    field :name, type: String
    embedded_in :band
  end

最后存儲(chǔ)的結(jié)果如下


  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "label" : {
      "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
      "name" : "Mute",
    }
  }

31. Embeds Many

一對(duì)多的嵌入關(guān)聯(lián)關(guān)系,使用 embeds_many 和 embedded_in


  class Band
    include Mongoid::Document
    embeds_many :albums
  end

  class Album
    include Mongoid::Document
    field :name, type: String
    embedded_in :band
  end

最后存儲(chǔ)結(jié)果如下:


  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "albums" : [
      {
        "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
        "name" : "Violator",
      }
    ]
  }


32. Has One

一對(duì)一的關(guān)聯(lián)關(guān)系中,使用 has_one 和 belongs_to


  class Band
    include Mongoid::Document
    has_one :studio
  end

  class Studio
    include Mongoid::Document
    field :name, type: String
    belongs_to :band
  end

最后存儲(chǔ)結(jié)果如下


  # The parent band document.
  { "_id" : ObjectId("4d3ed089fb60ab534684b7e9") }

  # The child studio document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "band_id" : ObjectId("4d3ed089fb60ab534684b7e9")
  }

33. Has Many

一對(duì)多的關(guān)聯(lián)關(guān)系中,使用has_many 和 belongs_to


  class Band
    include Mongoid::Document
    has_many :members
  end

  class Member
    include Mongoid::Document
    field :name, type: String
    belongs_to :band
  end

最終存儲(chǔ)結(jié)果如下


  # The parent band document.
  { "_id" : ObjectId("4d3ed089fb60ab534684b7e9") }

  # A child member document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f1"),
    "band_id" : ObjectId("4d3ed089fb60ab534684b7e9")
  }

34. 多對(duì)多的關(guān)聯(lián)關(guān)系

has_and_belongs_to_many

第一種方式


  class Band
    include Mongoid::Document
    has_and_belongs_to_many :tags
  end

  class Tag
    include Mongoid::Document
    field :name, type: String
    has_and_belongs_to_many :bands
  end

第二種方式


  class Band
    include Mongoid::Document
    has_and_belongs_to_many :tags, inverse_of: nil
  end

  class Tag
    include Mongoid::Document
    field :name, type: String
  end

最終存儲(chǔ)結(jié)果如下


  # The band document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
    "tag_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
  }

  # The tag document.
  {
    "_id" : ObjectId("4d3ed089fb60ab534684b7f2"),
    "band_ids" : [ ObjectId("4d3ed089fb60ab534684b7e9") ]
  }

35. 回調(diào)函數(shù)

  • after_initialize
  • after_build
  • before_validation
  • after_validation
  • before_create
  • around_create
  • after_create
  • after_find
  • before_update
  • around_update
  • after_update
  • before_upsert
  • around_upsert
  • after_upsert
  • before_save
  • around_save
  • after_save
  • before_destroy
  • around_destroy
  • after_destroy

36. 索引

給普通的field添加索引


  class Person
    include Mongoid::Document
    field :ssn

    index({ ssn: 1 }, { unique: true, name: "ssn_index" })
  end

給 embedded document 添加索引


  class Person
    include Mongoid::Document
    embeds_many :addresses
    index "addresses.street" => 1
  end

給多個(gè)列添加索引


  class Person
    include Mongoid::Document
    field :first_name
    field :last_name

    index({ first_name: 1, last_name: 1 }, { unique: true })
  end

使用下面命令添加索引


  rake db:mongoid:create_indexes

亦提供了刪除所有二級(jí)索引的命令


   rake db:mongoid:remove_indexes

ruby-mongoid-tutorial

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

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

  • 2017年9月18日 星期一 晴 張榮軒媽媽 親子日記第15篇 每個(gè)周一的早晨,都是我一周中最焦慮的時(shí)候...
    愛意暖人心閱讀 363評(píng)論 0 1
  • 張東輝,焦點(diǎn)初級(jí)第43期堅(jiān)持原創(chuàng)分享第35天 天氣放晴,親情融融,姐姐、弟弟和我,三家人,一眾十幾人,抓住假期的尾...
    星悅傳奇閱讀 255評(píng)論 0 0
  • 人生之中低谷最多的應(yīng)該就是20幾歲的年紀(jì)吧,沒錢沒房沒車沒愛人甚至工作還是一塌糊涂。但最好的時(shí)光也是20幾歲,有夢(mèng)...
    芳點(diǎn)兒閱讀 489評(píng)論 0 1
  • 忙碌勞累的三月已經(jīng)過去,從四月開始,很多人都希望自己工作順利,家庭幸福,好運(yùn)常伴。沒錯(cuò)哦,有這個(gè)三個(gè)生肖在三月霉運(yùn)...
    時(shí)允舜閱讀 214評(píng)論 0 0

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