【问题标题】:Mongoid::Errors::MixedRelations in AnswersController#createAnswersController#create 中的 Mongoid::Errors::MixedRelations
【发布时间】:2015-06-04 12:04:02
【问题描述】:

保存答案时收到以下错误消息:

问题:由于答案是嵌入的,因此不允许通过关系关联从用户文档中引用 (n) 答案文档。摘要:为了正确访问用户的(n)答案,参考需要通过答案的根文档。在一个简单的情况下,这将需要 Mongoid 为根存储一个额外的外键,在更复杂的情况下,Answer 是多个级别的深度,则需要为层次结构中的每个父级存储一个键。解决方案:考虑不嵌入 Answer,或者在应用程序代码中以自定义方式进行密钥存储和访问。

上述错误是由于 AnswersController 中的代码 @answer.user = current_user 造成的。

我想将登录用户名保存到嵌入问题的答案中。

设计用户模型:

class User
  include Mongoid::Document
  has_many :questions
  has_many :answers

class Question

  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Slug

  field :title, type: String
  slug :title

  field :description, type: String
  field :starred, type: Boolean

  validates :title, :presence => true, :length => { :minimum => 20, :allow_blank => false }

  embeds_many :comments
  embeds_many :answers

  #validates_presence_of :comments

  belongs_to :user

end

class Answer

  include Mongoid::Document
  include Mongoid::Timestamps

  field :content, type: String

  validates :content, :presence => true,  :allow_blank => false

  embedded_in :question, :inverse_of => :answers

  #validates_presence_of :comments

  belongs_to :user

end

class AnswersController < ApplicationController

  def create
    @question = Question.find(params[:question_id])
    @answer = @question.answers.create(params[:answer].permit(:answerer, :content))
    @answer.user = current_user
    redirect_to @question, :notice => "Answer added!"
  end
end

使用 Rails 4、Ruby 2.2.2、Mongoid。

【问题讨论】:

  • 您在控制器中提到了:answerer,但我在您的模型中没有看到这一点。另外,我不明白为什么您的答案模型中有user_id

标签: ruby-on-rails ruby ruby-on-rails-4 mongoid


【解决方案1】:

这正是错误消息所说的内容。

您的答案模型嵌入在问题模型中。也就是说,您只能对 Question 文档执行“普通”查询,而不能对嵌入在此文档中的模型执行(实际上可以,但它更困难,并且不知何故扼杀了使用嵌入式文档的意义)。

因此,您可以获得给定答案的用户,但不能获得您在用户模型中声明的相反答案。

最简单的解决方案是从用户模型中删除 has_many :answers,但如果您想检索给定用户的答案列表,那么嵌入模型可能不是最佳解决方案:您应该使用关系模型。

为了清楚起见,你应该写belongs_to :user, inverse_of: nil

【讨论】:

  • 谢谢。您建议的修改后错误已解决。但是 current_user 没有保存在嵌入式答案文档中。不知道我错过了什么!
  • 那是因为你没有保存它。当您执行@answer = @question.answers.create(params[:answer].permit(:answerer, :content)) 时,.create 会将您的更改保存到数据库中(就像调用.new.save)。所以你想在设置答案的用户后打电话给@answer.save
  • 知道了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
相关资源
最近更新 更多