Ruby on rails 4 Mongoid模型赢得';t persist通过嵌入一个关系拥有一个

Ruby on rails 4 Mongoid模型赢得';t persist通过嵌入一个关系拥有一个,ruby-on-rails-4,mongoid,Ruby On Rails 4,Mongoid,我在基于mongoid4的rails 4应用程序中嵌入时遇到问题。在过去的两天里,我一直在到处寻找答案。这是代码 这是一个教会管理应用程序,带有一个服务模型,嵌入了一个团队和一个乐队。每个团队/乐队都有几个角色,例如“主持”、“交流”,这些角色指的是一个用户 我的模型: class Service include Mongoid::Document ... embeds_one :team, autobuild: true embeds_one :band, autobuild:

我在基于mongoid4的rails 4应用程序中嵌入时遇到问题。在过去的两天里,我一直在到处寻找答案。这是代码

这是一个教会管理应用程序,带有一个服务模型,嵌入了一个团队和一个乐队。每个团队/乐队都有几个角色,例如“主持”、“交流”,这些角色指的是一个用户

我的模型:

class Service
  include Mongoid::Document
  ...
  embeds_one :team, autobuild: true
  embeds_one :band, autobuild: true
  ...
  accepts_nested_attributes_for :team, :band
end

class Team
  include Mongoid::Document  

  embedded_in :service

  has_one :presidence, :class_name => 'User', autosave: true
  has_one :message, :class_name => 'User', autosave: true
  ...
end

class Band
  include Mongoid::Document
  has_one :lead, :class_name => 'User', autosave: true
  has_one :guitar, :class_name => 'User', autosave: true
  ...
  embedded_in :service
end

class User
  include Mongoid::Document
  embeds_one :profile

  belongs_to :team, :inverse_of => :presidence
  belongs_to :team, :inverse_of => :message

  belongs_to :band, :inverse_of => :lead
  belongs_to :band, :inverse_of => :guitar

  def fullname
    "#{profile.firstname} #{profile.lastname}"
  end

  def self.find_by_talent(talent)
    self.where("profile.talents.name" => talent)
  end
end
服务控制员:

# POST /services
# POST /services.json
def create
  @service = Service.new(service_params)
  respond_to do |format|
    if @service.save
      format.html { redirect_to @service, notice: 'Service was successfully created.' }
      format.json { render action: 'show', status: :created, location: @service }
    else
      format.html { render action: 'new' }
      format.json { render json: @service.errors, status: :unprocessable_entity }
    end
  end
end

...

def service_params
  params.require(:service).permit(:date, :time, :place, :name, :theme, :team => [:id, :precedence, :message ], :band => [:id, :lead, :guitar ])
end
以及_form.html.erb中的表单:

<%= form_for(@service) do |f| %>
  ...
  <%= f.fields_for @service.team  do |tf| %>
    <%= tf.collection_select :presidence, User.find_by_talent(:presidence), :_id, :fullname, {:include_blank => "select a person"} %>
    <%= tf.collection_select :message, User.find_by_talent(:message), :id, :fullname, {:include_blank => "select a person"} %>
  <% end %>
  <%= f.fields_for @service.band  do |bf| %>
    <%= bf.collection_select :lead, User.find_by_talent(:lead), :id, :fullname, {:include_blank => "select a person"} %>
    <%= bf.collection_select :guitar, User.find_by_talent(:guitar), :id, :fullname, {:include_blank => "select a person"} %>
  <% end %>
  ...
<% end %>

我猜我做错了什么,但我不知道它是在数据库模型中还是在表单中。。。或者其他任何事情……

您将无法这样做。创建嵌入文档时,其
\u id
及其所有数据将直接嵌入父文档中。这与关联不同,在关联中,
所属的文档获取指向其关联父文档的外键。因此,在这里,您的
用户
文档都有
团队id
乐队id
,但是当数据库试图获取文档时,它找不到它们,因为您无法直接查询嵌入的文档;您首先需要父文档。有关更多信息,请参阅

另一个潜在问题是在
用户
模型中有多个
属于
定义。这也会导致问题,因为对于其中的每一个,Mongoid都会尝试创建
团队id
乐队id
。您应该分别命名它们并指定类名;也许像
:主唱团队
:消息团队
:主唱乐队
:吉他乐队
等名字应该会告诉你这是什么样子

我建议将团队和乐队分开,而不是嵌入文档,因为当用户嵌入时,您将无法有效地引用他们


希望这有帮助。

非常感谢。我不得不改变我的整个模型结构。我想这就是我的痛处。
2.0.0-p195 :001 > s = Service.last
 => #<Service _id: 52ea18834d61631e7e020000, date: "2014-02-02", time: "10:00", place: "Where it's at", name: "My great name", theme: "The service's theme"> 
2.0.0-p195 :002 > s.team
 => #<Team _id: 52ea18834d61631e7e030000, > 
2.0.0-p195 :003 > s.team.presidence
 => nil 
Started POST "/services" for 127.0.0.1 at 2014-01-30 10:16:51 +0100
Processing by ServicesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ph6lbdHC2FbiANn/fGSzHWprenj3fWKXM40Hrsc5+AM=", "service"=>{"date"=>"2014-02-02", "name"=>"My great name", "theme"=>"The service's theme", "time"=>"10:00", "place"=>"Where it's at", "team"=>{"presidence"=>"52ea18324d61631e81010000", "message"=>"52ea18324d61631e81010000"}, "band"=>{"lead"=>"52ea18324d61631e81010000", "guitar"=>"52ea18324d61631e81010000"}}, "commit"=>"Create Service"}
  MOPED: 127.0.0.1:27017 COMMAND      database=admin command={:ismaster=>1} runtime: 0.6610ms
  MOPED: 127.0.0.1:27017 UPDATE       database=service_boot_camp_development collection=users selector={"band_id"=>BSON::ObjectId('52ea18834d61631e7e010000'), "_id"=>{"$nin"=>[]}} update={"$set"=>{"band_id"=>nil}} flags=[:multi]
                         COMMAND      database=service_boot_camp_development command={:getlasterror=>1, :w=>1} runtime: 0.5800ms
  MOPED: 127.0.0.1:27017 INSERT       database=service_boot_camp_development collection=services documents=[{"_id"=>BSON::ObjectId('52ea18834d61631e7e020000'), "date"=>"2014-02-02", "time"=>"10:00", "place"=>"Where it's at", "name"=>"My great name", "theme"=>"The service's theme", "team"=>{"_id"=>BSON::ObjectId('52ea18834d61631e7e030000')}, "band"=>{"_id"=>BSON::ObjectId('52ea18834d61631e7e010000')}}] flags=[]
                         COMMAND      database=service_boot_camp_development command={:getlasterror=>1, :w=>1} runtime: 2.7460ms