Как одна mongoid модель может запросить другую? - PullRequest
0 голосов
/ 30 сентября 2011

Если у меня есть модель под названием Product

class Product
  include Mongoid::Document

  field :product_id
  field :brand
  field :name
  ...

  belongs_to :store

А потом у меня есть модель под названием Store

class Store
  include Mongoid::Document

  field :name
  field :store_id
  ...

  has_many :products

  def featured_products
    Products.where(:feature.exists => true).and(store_id: self[:store_id]).asc(:feature).asc(:name)
  end

Как мне создать доступный @ store.featured_products, который является результатом этого запроса? Прямо сейчас я получаю сообщение об ошибке

uninitialized constant Store::Products

Ответы [ 2 ]

1 голос
/ 30 сентября 2011

Используйте Product, а не Products.

0 голосов
/ 07 сентября 2015

Я просто наткнулся на это в поисках чего-то другого, и хотя приведенный выше ответ верен, и вопрос устарел, он очень неэффективен для того, что спрашивают. Как я наткнулся на это, так могут и другие.

В приведенном выше примере показано, как связать продукты с только что представленными продуктами, поэтому такая модель будет работать быстрее (предполагается Mongoid 3.0 +):

class Product
  include Mongoid::Document

  field :product_id
  field :brand
  field :name
  field :feature
  ...

  belongs_to :store

  scope :featured, where(:feature.exists => true).asc(:feature).asc(:name)

end

class Store
  include Mongoid::Document

  field :name
  field :store_id
  ...

  has_many :products
end

Тогда вместо @ store.featured_products вы можете вызвать @ store.products.featured. Теперь, если вы предполагаете, что использовался Mongoid 2.x, как это было в 2011 году, и, глядя на это , то у Mongoid 1.x, возможно, не было областей действия, то же самое можно было бы сделать так:

class Product
  include Mongoid::Document

  field :product_id
  field :brand
  field :name
  field :feature
  ...

  belongs_to :store
end

class Store
  include Mongoid::Document

  field :name
  field :store_id
  ...

  has_many :products

  def featured_products
     self.products.where(:feature.exists => true).asc(:feature).asc(:name)
  end
end

Теперь причина того, что оба они более эффективны, чем просто логический поиск в коллекции Products, заключается в том, что они начинаются с создания курсора через поле _id. Это индексируется и ограничивает последующий запрос только соответствующими документами. Разница будет заметна на большинстве размеров коллекции, однако чем больше будет расти коллекция, тем больше времени будет потрачено на логическое значение всей коллекции.

...