使用 mongoid 进行反规范化

发布于 2024-11-02 17:15:04 字数 1569 浏览 0 评论 0原文

使用 mongoid 和 Rails 进行非规范化的最佳方法是什么?

使用“嵌入”关系似乎不起作用(或者除了嵌入整个原始文档之外没有任何用途)。

我目前的解决方案将非规范化属性存储并检索为 OrderedHash:

collection.update({_id: id, ...}, {..., denormalized: {_id: other.id, _type: other._type, a: other.a, b: other.b}}

def denormalized
  Mongoid::Factory.build(attributes[:denormalized]["_type"], attributes[:denormalized])
end

编辑:我应该提到我确实尝试过 https:/ /github.com/logandk/mongoid_denormalize

它展平非规范化属性(在下面的示例中,它将存储author_name而不是author: {name: "value"} 并且它不支持多个非规范化关系(例如作者:[{name:“First Co-Author”,_id:1},{name:“Second Co-Author”,_id:2}])

编辑:请求一个示例

class User # this class uses STI so _type field is important
  include Mongoid::Document

  field :name # this is the field I want to de-normalize to where Users are referenced

   def write_book
     Book.create!({title: "Some Text", author: {_id: self.id, _type: self._type, name: self.name})
   end
end

class Book
  include Mongoid::Document

  field :title

  # embeds_one :author, polymorphic: true
  # tried this but it doesn't seem to be correct usage... it sort of works but
  # I run into problems with cycles and infinite loops when used extensively
  # because (I think) of how mongoid works internally, expecting embeds_one
  # to mean something different

  def author
    Mongoid::Factory.build(attributes[:author]["_type"], attributes[:author])
  end
end

正确的解决方案将具有ActiveModel方法 。例如 new_record? 以及 *_path 和 *_url 路由助手。

What is the best way to de-normalize with mongoid and Rails?

Using the "embedded" relationships does not appear to work (or be intended for anything but embedding the entire, original documents).

My present solution stores and retrieved the de-normalized attributes as an OrderedHash:

collection.update({_id: id, ...}, {..., denormalized: {_id: other.id, _type: other._type, a: other.a, b: other.b}}

def denormalized
  Mongoid::Factory.build(attributes[:denormalized]["_type"], attributes[:denormalized])
end

edit: I should mention that I did try https://github.com/logandk/mongoid_denormalize

It flattens out the denormalized attributes (in the example below, it would store author_name instead of author: {name: "value"} and it doesn't have support for multiple denormalized relations (e.g. authors: [{name: "First Co-Author", _id: 1}, {name: "Second Co-Author", _id: 2}])

edit: An example was requested.

class User # this class uses STI so _type field is important
  include Mongoid::Document

  field :name # this is the field I want to de-normalize to where Users are referenced

   def write_book
     Book.create!({title: "Some Text", author: {_id: self.id, _type: self._type, name: self.name})
   end
end

class Book
  include Mongoid::Document

  field :title

  # embeds_one :author, polymorphic: true
  # tried this but it doesn't seem to be correct usage... it sort of works but
  # I run into problems with cycles and infinite loops when used extensively
  # because (I think) of how mongoid works internally, expecting embeds_one
  # to mean something different

  def author
    Mongoid::Factory.build(attributes[:author]["_type"], attributes[:author])
  end
end

The correct solution would have ActiveModel methods such as new_record? working as well as the *_path and *_url routing helpers.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的他你的她 2024-11-09 17:15:05

这会将用户存储为书中嵌入的作者文档。

class User
  include Mongoid::Document
end

#instead of the write book method, you could just do this:
book = Book.create(title: "Old Man And The Sea", users: [user])

class Book
  include Mongoid::Document

  embeds_many :authors

  field :title

  def users=(users)
    users.each do |user|
      authors.build(user: user, name: user.name)
    end
  end
end

class Author
  include Mongoid::Document

  embedded_in :book
  referenced_in :user

  field :name
end

This will store the user as an embedded author document inside the book.

class User
  include Mongoid::Document
end

#instead of the write book method, you could just do this:
book = Book.create(title: "Old Man And The Sea", users: [user])

class Book
  include Mongoid::Document

  embeds_many :authors

  field :title

  def users=(users)
    users.each do |user|
      authors.build(user: user, name: user.name)
    end
  end
end

class Author
  include Mongoid::Document

  embedded_in :book
  referenced_in :user

  field :name
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文