Ruby on rails& mongoid - 关系管理belongs_to,has_many

时间:2017-04-28 12:32:20

标签: ruby-on-rails mongoid

我有mongoid / rails关系的问题,我知道这个问题有很多主题,但我找不到任何帮助我... 我有这些模型:

class Project
  include Mongoid::Document

  belongs_to :owner, :class_name => 'User', inverse_of: :projects
  has_many :members
end

class Member
  include Mongoid::Document

  belongs_to :project, inverse_of: :members
  belongs_to :user
end

class User
  include Mongoid::Document

  has_many :projects, inverse_of: :user

end

当我尝试将用户记录为成员时,出现此错误:

Mongoid::Errors::InverseNotFound (
message:
  When adding a(n) User to Project#members, Mongoid could not determine the inverse foreign key to set. The attempted key was 'project_id'.
summary:
  When adding a document to a relation, Mongoid attempts to link the newly added document to the base of the relation in memory, as well as set the foreign key to link them on the database side. In this case Mongoid could not determine what the inverse foreign key was.
resolution:
  If an inverse is not required, like a belongs_to or has_and_belongs_to_many, ensure that :inverse_of => nil is set on the relation. If the inverse is needed, most likely the inverse cannot be figured out from the names of the relations and you will need to explicitly tell Mongoid on the relation what the inverse is.

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

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

我不明白为什么,我认为关系和反向关系有问题,但我不知道如何解决这个问题。

1 个答案:

答案 0 :(得分:0)

class Project
  include Mongoid::Document

  belongs_to :owner, :class_name => 'User', inverse_of: :projects
  has_many :members
  has_many :users
end

但我不认为你的建模实际上会完成你想要的。在关系数据库中,您将使用与连接表的间接关联:

class User < ActiveRecord::Base
  has_many :memberships 
  has_many :projects, through: :memberships
end

class Membership < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

class Project < ActiveRecord::Base
  has_many :memberships 
  has_many :members, through: :memberships, 
                     source: :user
end 

但在Mongoland没有连接,所以我们需要使用不同的嵌入方法:

class Project
  # ...
  embeds_many :users
end

class User 
  # ...
  embedded_in :project
end

如果您需要能够将数据添加到中间模型,您可以伪造间接关联:

class Project
  # ...
  embeds_many :memberships

  def members
    Patient.in(id: memberships.pluck(:user_id))
  end
end

class Membership
  # ...
  field :approved, type: Boolean
  belongs_to :user
  embedded_in :project
end

class User 
  # ...
  def projects
    Project.where("members.user_id" => id).all
  end
end