2014-01-30 49 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