我在嵌入基于mongoid4的rails 4 app中遇到了麻烦。在过去的两天里,我一直在寻找答案。所以这是代码。
这是一个教会管理应用程序,具有服务模型,嵌入团队和乐队。每个团队/乐队都有几个角色,例如“总统”,“交流”,指的是用户。
我的模特:
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看起来也很奇怪,结尾逗号......
以下是我的rails日志的内容:
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
我想我做错了什么,但我不知道它是在数据库模型中还是在表单中......或其他任何东西......
答案 0 :(得分:2)
你将无法这样做。创建嵌入文档时,其_id
及其所有数据都直接嵌入父文档中。这与关联形成对比,其中具有belongs_to
的文档获得指向其关联父文档的外键。在这里,您的User
文档每个都有team_id
和band_id
,但是当数据库尝试获取文档时,它无法找到它们,因为您无法直接查询嵌入式文件;你首先需要父文件。有关更多信息,请参阅the Mongoid documentation。
另一个潜在问题是您在belongs_to
模型中有多个User
定义。这也会导致问题,因为对于其中的每一个,Mongoid将尝试创建team_id
和band_id
。您应该单独命名并指定类名;也许像:presiding_team
和:message_team
,:lead_band
和:guitar_band
这样的名称等等This answer应该会向您展示它的样子。
我建议将团队和乐队分开引用文档而不是嵌入文档,因为在嵌入文档时,您将无法有效地引用用户。
希望这有帮助。