【问题标题】:Ruby on rails & mongoid - relation management belongs_to, has_manyRuby on rails & mongoid - 关系管理belongs_to, has_many
【发布时间】:2017-09-26 13:57:09
【问题描述】:

我有一个关于 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):

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

【问题讨论】:

    标签: ruby-on-rails mongoid


    【解决方案1】:
    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 
    

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

    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
    

    【讨论】:

    • 感谢您的回答!我认为嵌入是一个好主意,但我该如何为所有者用户和只是成员的用户管理它?
    • 我不完全确定,但我认为您可以使用类选项 embeds_many :members, class_name: 'User'embeds_one :owner, class_name: 'User' 来设置带有别名的嵌入。但是我已经很久没有使用 Mongoid了。
    • 我不确定最终嵌入它是一个好主意,因为我不希望我的用户依赖于项目,我想要项目和用户之间的关系
    • 查看我的编辑如何解决嵌入“加入”文档的限制。我这台机器上没有 mongodb,所以我没有测试它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-21
    • 2012-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多