2014-01-30 63 views
2

我遇到了嵌入在基于mongoid4的rails 4应用程序中的问题。过去两天我一直在寻找答案。所以这里是代码。Mongoid模型不会坚持has_one通过embeds_one关系

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

我的模型:

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 %> 

当创建一个服务,一切似乎运行良好,但这是我在控制台中得到的:

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 

为什么不创建s.team.presidence? s.team看起来奇怪,也与结束逗号......

这里是我的导轨的内容记录:

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 

我想我做错了什么,但我不知道如果它在数据库模型或形式...或其他任何东西...

回答

2

你将无法这样做。在创建嵌入式文档时,其_id及其所有数据都直接嵌入到父文档中。这与关联相反,belongs_to的文档获取指向其关联父文档的外键。因此,在这里,您的User文档中的每个文档都有一个team_idband_id,但是当数据库尝试获取文档时,它找不到它们,因为您无法直接查询嵌入文档;你首先需要父文件。有关更多信息,请参见the Mongoid documentation

另一个潜在的问题是您在User模型中有多个belongs_to定义。这也会导致一个问题,因为对于其中的每一个,Mongoid将尝试创建一个team_idband_id。你应该单独命名它们并指定一个类名;也许这样的名称,如:presiding_team:message_team,:lead_band:guitar_bandThis answer应该告诉你看起来像什么。

我会建议让团队和乐队分开引用文档而不是嵌入文档,因为在嵌入文档时无法有效引用用户。

希望这会有所帮助。

+0

非常感谢。我不得不改变我的整个模型结构。我想那是令人痛苦的。 – Weengs